OpenClinica / enketo-oc

OpenClinica's fork of the Enketo web forms monorepo
Apache License 2.0
0 stars 5 forks source link

Date function via number introduces time and timezone unnecessarily #116

Open pbowen-oc opened 4 years ago

pbowen-oc commented 4 years ago

This is related to issue OpenClinica/enketo-express-oc#197.

Calling the date() function with a numeric argument is resulting in a date with time and timezone around the DST start/end dates. datetest1.xml.txt

Around DST boundaries: Annotation 2020-06-19 021250 Annotation 2020-06-19 021316

Not around DST boundaries: Annotation 2020-06-19 023937 Annotation 2020-06-19 021229

Another sample with just a calculation: datetest2.xml.txt Annotation 2020-06-19 023844

pbowen-oc commented 4 years ago

@MartijnR - I can't understand this behavior. Perhaps it is the number() function? I also tried with decimal-date-time() and got similar results.

Related to that, is there any functional difference between decimal-date-time() and number() if a date is passed in? Is there any reason to use one over the other to support date arithmetic (such as calculating the date x days from a given date)?

MartijnR commented 4 years ago

I don't think there is a difference actually. I never realized that.

I think it's debatable what is correct here, since calculation type is a string. If you use date or dateTime types (in the unreleased pxyform), you should get a predictable result. This is a situation where this new pyxform feature will be very helfpul.

In any case, would be best to hold off on this until the new XPath evaluator is operational.

pbowen-oc commented 4 years ago

@MartijnR - I switch the form to using decimal and date items instead of calculates. The date still ends up being 1 hour off when the value is moving between timezones.

The expectation is that adding to 10 days (or whatever number) will consistently give you the date 10 days in the future from that date. Given the timezone handling now, it will give you a date 1 day short in some cases. I am assuming this is dependent on the viewing user's timezone settings, so it is not possible to even somewhat work around by adding/subtracting an hour in certain cases.

We've been doing date arithmetic using string manipulation (which is incredibly cumbersome), so I was hoping the date() function would work as a reliable inverse of decimal-date-time(). If it needs to wait for the new evaluator, we can wait.

datetest4.xml.txt

Annotation 2020-06-23 235743

MartijnR commented 4 years ago

Thanks. I think the solution is probably to let enketo-core convert date types to the nearest date, instead of just lobbing off the time component.

pbowen-oc commented 4 years ago

As we discussed earlier, I think this might be better as a custom function that is like the current date() function but rounds to the nearest midnight.

pbowen-oc commented 4 years ago

I was thinking about this more and noticing the additional .16666 or .20833 days added onto the result due to my timezone. Since the dates entered onto our forms are verbatim dates, I'd want them all to be treated as timezone-free (for example, UTC-0 with no DST). An approach that rounds to the nearest midnight would fail for timezones around UTC+/-12 (or +/-11 when this issue occurs). So, I'd want a function that can leave timezone out right from the start.

In the meantime, we will work around the current behavior by adding an extra (1 div 24) days to calculated values that might be subject to this problem before converting back to a date to account for the potential hour discrepancy.