Calculations using Time

Hi,

We are using Commcare to enter data for a glucose tolerance test, which
requires readings to be entered at 30, 60, and 120 minutes after the start
of the test.

Is there a way which we can enter the start time and Commcare can calculate
when the other readings should be? - I would want this to calculate and
display as a label. ie. Time0+30minutes etc.....???

Is this possible? Please advise,

Thanks very much as always,

Natasha

Hi Natasha,

you should be able to use the format-date command documented on this page:
https://confluence.dimagi.com/display/commcarepublic/CommCare+Functions#CommCareFunctions-format-date

It lets you break apart dates in the below ways.

  • ‘%Y’ = year
  • ‘%y’ = 2 digit year
  • ‘%m’ = 0-padded month
  • ‘%n’ = numeric month
  • ‘%b’ = short text month (Jan, Feb, etc)
  • ‘%d’ = 0-padded day of month
  • ‘%e’ = day of month
  • ‘%H’ = 0-padded hour (24 hour time)
  • ‘%h’ = hour (24 hour time)
  • ‘%M’ = 0-padded minutes
  • ‘%S’ = 0-padded second
  • ‘%3’ = 0-padded milliseconds
  • ‘%a’ = three letter short text day (Sun, Mon, etc)

Regards,
Nick

Nick Nestle
Project Manager | Dimagi South Africa
+27 79 439 6081

··· On Wed, Jun 25, 2014 at 2:33 PM, Natasha Lelijveld < natasha.lelijveld@gmail.com> wrote:

Hi,

We are using Commcare to enter data for a glucose tolerance test, which
requires readings to be entered at 30, 60, and 120 minutes after the start
of the test.

Is there a way which we can enter the start time and Commcare can
calculate when the other readings should be? - I would want this to
calculate and display as a label. ie. Time0+30minutes etc.....???

Is this possible? Please advise,

Thanks very much as always,

Natasha

--
You received this message because you are subscribed to the Google Groups
"commcare-users" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to commcare-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Hi Nick,

thanks very much for that - and I will need to display the times in the
label, so that is helpful.

BUT I want to display an entered time PLUS 30 minutes - how do I add the 30
minutes??

Something like: format-date(/data/my_time +30, %H:%M:%S') ??

Thanks very much for help me.

··· On Wednesday, 25 June 2014 15:14:45 UTC+2, Nick Nestle wrote: > > Hi Natasha, > > you should be able to use the format-date command documented on this page: > > https://confluence.dimagi.com/display/commcarepublic/CommCare+Functions#CommCareFunctions-format-date > > It lets you break apart dates in the below ways. > > > - ‘%Y’ = year > - ‘%y’ = 2 digit year > - ‘%m’ = 0-padded month > - ‘%n’ = numeric month > - ‘%b’ = short text month (Jan, Feb, etc) > - ‘%d’ = 0-padded day of month > - ‘%e’ = day of month > - ‘%H’ = 0-padded hour (24 hour time) > - ‘%h’ = hour (24 hour time) > - ‘%M’ = 0-padded minutes > - ‘%S’ = 0-padded second > - ‘%3’ = 0-padded milliseconds > - ‘%a’ = three letter short text day (Sun, Mon, etc) > > > > Regards, > Nick > > Nick Nestle > Project Manager | Dimagi South Africa > +27 79 439 6081 > > > > On Wed, Jun 25, 2014 at 2:33 PM, Natasha Lelijveld <natasha....@gmail.com > wrote: > >> Hi, >> >> We are using Commcare to enter data for a glucose tolerance test, which >> requires readings to be entered at 30, 60, and 120 minutes after the start >> of the test. >> >> Is there a way which we can enter the start time and Commcare can >> calculate when the other readings should be? - I would want this to >> calculate and display as a label. ie. Time0+30minutes etc.....??? >> >> Is this possible? Please advise, >> >> Thanks very much as always, >> >> Natasha >> >> -- >> You received this message because you are subscribed to the Google Groups >> "commcare-users" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to commcare-user...@googlegroups.com . >> For more options, visit https://groups.google.com/d/optout. >> > >

Hi Natasha,

I don't think there's a command to add minutes to a time (someone please
correct me if I'm wrong on that
) so unfortunately it's a little trickier.
You'll have to pull the hour, minute, and second out separately, then add
30 to the minutes, then put the three pieces back together to display it as
a string. It should be something like the below. The if statements are to
check if you need to increment the hour:

Original times saved to a data node:
/data/minute = format-date(/data/my_date,%M)
/data/hour = format-date(/data/my_date,%H)
/data/second = format-date(/data/my_date,%S)

New times based on the old time:
/data/new_minute = if(/data/minute > 30, /data/minute - 30, /data/minute
+30)
/data/new_hour = if(/data/minute < 30, /data/hour, if(/data/hour = 12, 1,
/data/hour + 1)) <=== change to 24 for a 24-hour clock
/data/new_time = concat(/data/new_hour, ":", /data/new_minute, ":",
/data/second)

Important to note this doesn't result in a new date field, it's just a
string that displays the time.

Hope that helps!

  • Nick

Nick Nestle
Project Manager | Dimagi South Africa
+27 79 439 6081

··· On Wed, Jun 25, 2014 at 3:44 PM, Natasha Lelijveld < natasha.lelijveld@gmail.com> wrote:

Hi Nick,

thanks very much for that - and I will need to display the times in the
label, so that is helpful.

BUT I want to display an entered time PLUS 30 minutes - how do I add the
30 minutes??

Something like: format-date(/data/my_time +30, %H:%M:%S') ??

Thanks very much for help me.

On Wednesday, 25 June 2014 15:14:45 UTC+2, Nick Nestle wrote:

Hi Natasha,

you should be able to use the format-date command documented on this
page: Home - CommCare Public - CommCare Public
CommCare+Functions#CommCareFunctions-format-date

It lets you break apart dates in the below ways.

  • ‘%Y’ = year
  • ‘%y’ = 2 digit year
  • ‘%m’ = 0-padded month
  • ‘%n’ = numeric month
  • ‘%b’ = short text month (Jan, Feb, etc)
  • ‘%d’ = 0-padded day of month
  • ‘%e’ = day of month
  • ‘%H’ = 0-padded hour (24 hour time)
  • ‘%h’ = hour (24 hour time)
  • ‘%M’ = 0-padded minutes
  • ‘%S’ = 0-padded second
  • ‘%3’ = 0-padded milliseconds
  • ‘%a’ = three letter short text day (Sun, Mon, etc)

Regards,
Nick

Nick Nestle
Project Manager | Dimagi South Africa
+27 79 439 6081

On Wed, Jun 25, 2014 at 2:33 PM, Natasha Lelijveld <natasha....@gmail.com wrote:

Hi,

We are using Commcare to enter data for a glucose tolerance test, which
requires readings to be entered at 30, 60, and 120 minutes after the start
of the test.

Is there a way which we can enter the start time and Commcare can
calculate when the other readings should be? - I would want this to
calculate and display as a label. ie. Time0+30minutes etc.....???

Is this possible? Please advise,

Thanks very much as always,

Natasha

--
You received this message because you are subscribed to the Google
Groups "commcare-users" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to commcare-user...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups
"commcare-users" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to commcare-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Hi Nick,

Thank you - I think your instructions are on the correct lines of what I
want to do (I don't need to create a new date field - i just want it to
calculate the new times and display them so that the study team can write
it down - saves them calculating). However, when deployed the form for
test, an error appears when it comes to entering the 'my time' (or time
Zero as we like to call it). The form says "there is a bug in one of your
form's XPath Expressions for data/minute. :type mismatch converting string
to date"

This is what I did:
Time is entered at baseline using the 'time' question (/data/T0)
then I created 3 'hidden values' with the following calulate conditions for
minute, hour and second:

format-date(/data/T0_a,"%M")

format-date(/data/T0_a,"%H")

format-date(/data/T0_a,"%S")

(Commcare doesn't seem to like the above instructions..?)

and then I created 3 more hidden values new_minute, new_hour and new_time,
with the following calculate conditions:

if(/data/minute > 30, /data/minute - 30, /data/minute +30)

if(/data/minute < 30, /data/hour, if(/data/hour = 12, 1, /data/hour + 1))

concat(/data/new_hour, ":", /data/new_minute, ":", /data/second)

I then created a 'label' which reads: Child's 30 minutes test should be at

Not sure where I have gone wrong! If you can spot anything, do let me know.
If not, perhaps I will give up on this function and we will calculate the
times ourselves!

Thanks as always for helping,

Natasha

··· On Wednesday, 25 June 2014 16:16:04 UTC+2, Nick Nestle wrote: > > Hi Natasha, > > I don't think there's a command to add minutes to a time (*someone please > correct me if I'm wrong on that*) so unfortunately it's a little > trickier. You'll have to pull the hour, minute, and second out separately, > then add 30 to the minutes, then put the three pieces back together to > display it as a string. It should be something like the below. The if > statements are to check if you need to increment the hour: > > Original times saved to a data node: > /data/minute = format-date(/data/my_date,%M) > /data/hour = format-date(/data/my_date,%H) > /data/second = format-date(/data/my_date,%S) > > New times based on the old time: > /data/new_minute = if(/data/minute > 30, /data/minute - 30, /data/minute > +30) > /data/new_hour = if(/data/minute < 30, /data/hour, if(/data/hour = 12, 1, > /data/hour + 1)) <=== change to 24 for a 24-hour clock > /data/new_time = concat(/data/new_hour, ":", /data/new_minute, ":", > /data/second) > > Important to note this doesn't result in a new date field, it's just a > string that displays the time. > > Hope that helps! > > - Nick > > > > Nick Nestle > Project Manager | Dimagi South Africa > +27 79 439 6081 > > > > On Wed, Jun 25, 2014 at 3:44 PM, Natasha Lelijveld <natasha....@gmail.com > wrote: > >> Hi Nick, >> >> thanks very much for that - and I will need to display the times in the >> label, so that is helpful. >> >> BUT I want to display an entered time PLUS 30 minutes - how do I add the >> 30 minutes?? >> >> Something like: format-date(/data/my_time +30, %H:%M:%S') ?? >> >> Thanks very much for help me. >> >> >> On Wednesday, 25 June 2014 15:14:45 UTC+2, Nick Nestle wrote: >> >>> Hi Natasha, >>> >>> you should be able to use the format-date command documented on this >>> page: https://confluence.dimagi.com/display/commcarepublic/ >>> CommCare+Functions#CommCareFunctions-format-date >>> >>> It lets you break apart dates in the below ways. >>> >>> >>> - ‘%Y’ = year >>> - ‘%y’ = 2 digit year >>> - ‘%m’ = 0-padded month >>> - ‘%n’ = numeric month >>> - ‘%b’ = short text month (Jan, Feb, etc) >>> - ‘%d’ = 0-padded day of month >>> - ‘%e’ = day of month >>> - ‘%H’ = 0-padded hour (24 hour time) >>> - ‘%h’ = hour (24 hour time) >>> - ‘%M’ = 0-padded minutes >>> - ‘%S’ = 0-padded second >>> - ‘%3’ = 0-padded milliseconds >>> - ‘%a’ = three letter short text day (Sun, Mon, etc) >>> >>> >>> >>> Regards, >>> Nick >>> >>> Nick Nestle >>> Project Manager | Dimagi South Africa >>> +27 79 439 6081 >>> >>> >>> >>> On Wed, Jun 25, 2014 at 2:33 PM, Natasha Lelijveld < natasha....@gmail.com> wrote: >>> >>>> Hi, >>>> >>>> We are using Commcare to enter data for a glucose tolerance test, which >>>> requires readings to be entered at 30, 60, and 120 minutes after the start >>>> of the test. >>>> >>>> Is there a way which we can enter the start time and Commcare can >>>> calculate when the other readings should be? - I would want this to >>>> calculate and display as a label. ie. Time0+30minutes etc.....??? >>>> >>>> Is this possible? Please advise, >>>> >>>> Thanks very much as always, >>>> >>>> Natasha >>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "commcare-users" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to commcare-user...@googlegroups.com. >>>> >>>> For more options, visit https://groups.google.com/d/optout. >>>> >>> >>> -- >> You received this message because you are subscribed to the Google Groups >> "commcare-users" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to commcare-user...@googlegroups.com . >> For more options, visit https://groups.google.com/d/optout. >> > >

Hi Natasha,

I think CommCare does not realize your /data/T0_a is a date.

I think a quick fix is to change your format-date expressions to be:
*format-date(date(/data/T0_a),"%M").
*This tells CommCare to treat /data/T0_a as a date and not a string. How
are you recording that value to begin with? Is it just a date questions, or
are you doing some math on a date field. Whenever you do math on a date
field it's best to wrap it with date() to make sure CC knows it's a date.

-Nick

Nick Nestle
Project Manager | Dimagi South Africa
+27 79 439 6081

··· On Thu, Jun 26, 2014 at 4:58 PM, Natasha Lelijveld < natasha.lelijveld@gmail.com> wrote:

Hi Nick,

Thank you - I think your instructions are on the correct lines of what I
want to do (I don't need to create a new date field - i just want it to
calculate the new times and display them so that the study team can write
it down - saves them calculating). However, when deployed the form for
test, an error appears when it comes to entering the 'my time' (or time
Zero as we like to call it). The form says "there is a bug in one of your
form's XPath Expressions for data/minute. :type mismatch converting string
to date"

This is what I did:
Time is entered at baseline using the 'time' question (/data/T0)
then I created 3 'hidden values' with the following calulate conditions
for minute, hour and second:

format-date(/data/T0_a,"%M")

format-date(/data/T0_a,"%H")

format-date(/data/T0_a,"%S")

(Commcare doesn't seem to like the above instructions..?)

and then I created 3 more hidden values new_minute, new_hour and new_time,
with the following calculate conditions:

if(/data/minute > 30, /data/minute - 30, /data/minute +30)

if(/data/minute < 30, /data/hour, if(/data/hour = 12, 1, /data/hour + 1))

concat(/data/new_hour, ":", /data/new_minute, ":", /data/second)

I then created a 'label' which reads: Child's 30 minutes test should be at

Not sure where I have gone wrong! If you can spot anything, do let me
know. If not, perhaps I will give up on this function and we will calculate
the times ourselves!

Thanks as always for helping,

Natasha

On Wednesday, 25 June 2014 16:16:04 UTC+2, Nick Nestle wrote:

Hi Natasha,

I don't think there's a command to add minutes to a time (someone
please correct me if I'm wrong on that
) so unfortunately it's a little
trickier. You'll have to pull the hour, minute, and second out separately,
then add 30 to the minutes, then put the three pieces back together to
display it as a string. It should be something like the below. The if
statements are to check if you need to increment the hour:

Original times saved to a data node:
/data/minute = format-date(/data/my_date,%M)
/data/hour = format-date(/data/my_date,%H)
/data/second = format-date(/data/my_date,%S)

New times based on the old time:
/data/new_minute = if(/data/minute > 30, /data/minute - 30, /data/minute
+30)
/data/new_hour = if(/data/minute < 30, /data/hour, if(/data/hour = 12, 1,
/data/hour + 1)) <=== change to 24 for a 24-hour clock
/data/new_time = concat(/data/new_hour, ":", /data/new_minute, ":",
/data/second)

Important to note this doesn't result in a new date field, it's just a
string that displays the time.

Hope that helps!

  • Nick

Nick Nestle
Project Manager | Dimagi South Africa
+27 79 439 6081

On Wed, Jun 25, 2014 at 3:44 PM, Natasha Lelijveld <natasha....@gmail.com wrote:

Hi Nick,

thanks very much for that - and I will need to display the times in the
label, so that is helpful.

BUT I want to display an entered time PLUS 30 minutes - how do I add the
30 minutes??

Something like: format-date(/data/my_time +30, %H:%M:%S') ??

Thanks very much for help me.

On Wednesday, 25 June 2014 15:14:45 UTC+2, Nick Nestle wrote:

Hi Natasha,

you should be able to use the format-date command documented on this
page: https://confluence.dimagi.com/display/commcarepublic/CommCa
re+Functions#CommCareFunctions-format-date

It lets you break apart dates in the below ways.

  • ‘%Y’ = year
  • ‘%y’ = 2 digit year
  • ‘%m’ = 0-padded month
  • ‘%n’ = numeric month
  • ‘%b’ = short text month (Jan, Feb, etc)
  • ‘%d’ = 0-padded day of month
  • ‘%e’ = day of month
  • ‘%H’ = 0-padded hour (24 hour time)
  • ‘%h’ = hour (24 hour time)
  • ‘%M’ = 0-padded minutes
  • ‘%S’ = 0-padded second
  • ‘%3’ = 0-padded milliseconds
  • ‘%a’ = three letter short text day (Sun, Mon, etc)

Regards,
Nick

Nick Nestle
Project Manager | Dimagi South Africa
+27 79 439 6081

On Wed, Jun 25, 2014 at 2:33 PM, Natasha Lelijveld < natasha....@gmail.com> wrote:

Hi,

We are using Commcare to enter data for a glucose tolerance test,
which requires readings to be entered at 30, 60, and 120 minutes after the
start of the test.

Is there a way which we can enter the start time and Commcare can
calculate when the other readings should be? - I would want this to
calculate and display as a label. ie. Time0+30minutes etc.....???

Is this possible? Please advise,

Thanks very much as always,

Natasha

--
You received this message because you are subscribed to the Google
Groups "commcare-users" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to commcare-user...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google
Groups "commcare-users" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to commcare-user...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups
"commcare-users" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to commcare-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.