Community Health Toolkit

XForm - A way to parse a timestamp to a human readable date and XForm's 'calculation' behaviour

Hi!

I’m making a form where I set field values after a promise is resolved, something like this:

$(input)
      .val(value)
      .trigger('change');

This value (rdt_session_time_started) can be a timestamp, like: 1628580917876. The user can see but not modify this value.

  1. Is there a way to format a timestamp to a human readable text? For example: Tue Aug 10 2021, 14:35:17

I’ve:

  • tried decimal-date-time(${rdt_session_time_started}) and format-date-time(${rdt_session_time_started}, "%Y-%n-%e %H:%M:%S") in the calculation, also by hardcoding the values decimal-date-time(1628580917876) but the result is wrong: NaN.
  • checked openrosa-xpath-evaluator and I believe timestamp is probably not supported.
  • created a note with a label calling a calculation field outside the group like for having another page when clicking next. Etc…

But still wondering if anyone know an Eketo/XForm way.

In the meantime to unblock myself, I’ve created a function in to parse timestamps to Date objects in medic-xpath-extensions.
At the end it looks like this:
format-date-time(parseTimestampToDate(${rdt_session_time_started}), "%Y-%n-%e %H:%M:%S")

What happens is that parseTimestampToDate runs only when loading the form and not when the value of the field changes, this field is either readonly or hidden because the user can’t modify the value.

  1. Not sure if this is because the field is readonly or hidden and the calculation doesn’t trigger because of that, or because the value is added after a promise resolved, or if I’m parseTimestampToDate in the wrong place. What do you think?

PD: The code and forms linked here are still in development and may contain experiments :grimacing:

2 Likes

Looking at the openrosa-xpath-evaluator, it looks like it’s using setDate to actually calculate the date object.
So, if you pass it your calculated the number of days for your timestamp (divide it by 86400000) and use format-date it should work.

My demo form has:

<bind nodeset="/date-input/adate" calculate="format-date(1628622414635 div 86400000, '%Y')" type="string"/>

and shows 2021 :slight_smile:

You won’t be able to get units under one day with this method, though.

1 Like

Thanks Diana for the fast reply!

That’s good alternative, however for this scenario we also need hours, minutes and seconds so the user can take timely actions.

I was able to fix my function (parse-timestamp-to-date) and from its output I can use regular XForms functions:
format-date-time(parse-timestamp-to-date(${rdt_session_time_started}), "%e %b, %Y at %H:%M:%S")

I’ll send it for feedback.