I am working on an electronic logbook for my first year students. in the
logbook there is a clock-in / clock-out module which contains forms to
clock in for the day and clock out at the end of the day. I would like to
calculate the hours and mins that they have worked and display it on the
clock out form when they are clocking out. I have seen commcare
documentation to support calculations using dates, but I am unsure of how
to calculate hours and minutes using time. is there a calculation/logic
for that?
You can use the "now()" function to get the current date and time. To use
the result it in calculations, you must convert it to a decimal value using
the "double()" function. The double function will convert the now() value
to a number that represents the date/time in days. This is similar to doing
calculations on dates, when you use int() to convert a date value into
number of days.
When the user "checks in" in you can capture the full date and time with a
hidden value with a calculation:
double(now())
Save the hidden value to the case. When the user "checks out" you can load
that value into the "checks out" form (I'll call the hidden value
'log_in_time').
Create another hidden value (I'll call it 'time_worked') represent the
amount of time that has passed, by calculating:
double(now()) - double(/data/log_in_time)
The result is a decimal value in days/fractions of days. To convert to
hours and minutes, you can do the following calculations:
int(/data/time_worked * 24) = (rounded down) the # of hours
int(((/data/time_worked*24) - int(/data/time_worked * 24)) * 60) = (rounded
down) the # of minutes worked.
I know that's a little bit complex. Please let me know if you need a hand
testing anything out or getting this to work.
-Clayton
···
On Sun, Apr 13, 2014 at 10:33 AM, Ameera Hamid wrote:
Hi Everyone,
I am working on an electronic logbook for my first year students. in the
logbook there is a clock-in / clock-out module which contains forms to
clock in for the day and clock out at the end of the day. I would like to
calculate the hours and mins that they have worked and display it on the
clock out form when they are clocking out. I have seen commcare
documentation to support calculations using dates, but I am unsure of how
to calculate hours and minutes using time. is there a calculation/logic
for that?
I'm going to test it out and will let you know if i need more assistance.
Kind regards,
Ameera
···
On Sunday, 13 April 2014 16:33:23 UTC+2, Ameera Hamid wrote:
>
> Hi Everyone,
>
> I am working on an electronic logbook for my first year students. in the
> logbook there is a clock-in / clock-out module which contains forms to
> clock in for the day and clock out at the end of the day. I would like to
> calculate the hours and mins that they have worked and display it on the
> clock out form when they are clocking out. I have seen commcare
> documentation to support calculations using dates, but I am unsure of how
> to calculate hours and minutes using time. is there a calculation/logic
> for that?
>
> Any help would be greatly appreciated!
>
> Thanks,
> Ameera
>
I am working on this exact calculation in Commcare but its not working. What i want to capture is the time taken for a coaching session, see steps i took below:
We have two time questions, one for start_time and the other for end_time
Have you tried seeing what the intermediate value of each of those calculations is?
The Data Preview "Evaluate XPath" tool is very helpful for trying different calculations and seeing what the results are piece by piece to break down where issues are occuring.
Specifically:
We have two time questions, one for start_time and the other for end_time
I'm not sure that this is producing the result you might be hoping for, as I'm not sure that Time entry questions actual convert helpfully to numbers automatically.
My web apps view doesn't show me all the applications within my project space for me to test my expressions. Is there something i can do to rectify this?
Within Live Preview you'd see the Data Preview Pane as a floating button on the lower right hand portion of the UI as in the screenshot below, underneath the "Submit" button
would in theory produce a number of minutes that could be subtracted from a similar calculation for a "time of end", but that wouldn't properly calculate for times that 'wrap around' (IE: 11:30pm -> 1:30am) or other edge cases.
It's surprising to me that those expressions would ever be blank, I'd expect them to produce errors, "NaN", or '0' as an output if something wasn't right.
It would help to split up those expressions to try to pinpoint what parts of them are not producing the expected result.
Have you tried out the "Evaluate XPath" feature of Data Preview? In your screenshots, there is a "Menu" option in the top right. If you click that, you should see an option called "Evaluate XPath", which will take you to a screen where you can try out various expressions on the form without needing to reload everything each time. This should make it pretty quick to test out each part of those expressions to see where it's going wrong.
Note that instead of #form/timestart, you'll need to reference /data/timestart, as that #form syntax only works in the form builder.
Ah, that's the problem - it should be /data/start_time, not #data/start_time. The expression tester doesn't support easy references. Additionally, the substring-before function takes two arguments. You can read more about it here. I believe the expression should be
int(substring-before(/data/timestart, “:”))
Gives the "hour" portion of the timestamp. To access the "minute" portion, use int(substring-after(/data/timestart, “:”))
Clayton's message from earlier proposed this calculation: int(substring-before(#form/timestart, “:”)) * 60 + int(substring-after(#form/timestart, “:”))
So in full, you could make a hidden value start_minutes with the calculation int(substring-before(/data/timestart, “:”)) * 60 + int(substring-after(/data/timestart, “:”))
And a hidden value end_minutes with the calculation int(substring-before(/data/timeend, “:”)) * 60 + int(substring-after(/data/timeend, “:”))
Then the overall result would be /data/end_minutes - /data/start_minutes
I want to set up a system to check how long it takes for people to fill in sections of a single form (rather than use multiple forms). So I've used the double(now()) work-around.
However, hidden values are either instantiated immediately (using the default option), or every time a question is answered (using the calculate option). Even if I use the display condition, the hidden values will be instantiated every time a question is answered as soon as the display condition is met.
Is there no way to get hidden values to instantiate just once (say the first time the display condition is met) and then never again after? It might be a little bit error-prone to use if people decide to go back to previously answered questions, but given the vast majority of people just fill the form in a linear fashion from start to end, it should work fine most of the time.