I feel like I’m writing a Talk post every year or so dealing with the problems of time zones and as I’ve been going through the O3 app I’m running into some new issues, but they are generally caused by one issue that seems tricky to solve:
How do we represent a simple date (with no time) within a timezoned datetime data structure?
That is, how do we represent “May 30th, 2023” using a JavaScript Date object in a way that can be consistently interpreted across time zones?
The most common examples of this problem are when entering an encounter dates, observation of type date, or a program enrollment/completion dates.
For example, say that we are entering a retrospective encounter and use a datepicker to set the encounter date. No time component is set, and so our general way of handling that is to set the time component of the encounter date time to 00:00.
But then, if you view that data in a time zone that is behind the entry time zone, the date is shifted to the day before (ie … if you enter in EDT and view in PDT, then 2023-05-31T00:00:00.000-0400 gets converted to 2023-05-30T21:00:00.000-0700) and f you view the data in the time zone that is ahead of the entry time zone, you get the correct date, but there’s now a time component so it’s unclear if you really mean the encounter happened at that specific time, or are just specifying that it happens on that day (ie … if you enter in EDT and view in UTC, then 2023-05-31T00:00:00.000-0400 gets converted to 2023-05-31T04:00:00.000-0000, which could be interpreted as an encounter that actually happened at 4 in the morning UTC).
I’m not sure what the answer is, and we may just have a fundamental problem that we have fields like “encounter_datetime” that we sometime want to have a time component (generally when entering encounters point-of-care, real-time) and sometimes don’t (generally when doing retrospective entry where we usually only know the date an encounter occurred, not the time).
We’ve hacked around this on the server in O2 (generally by having the client strip off the timezone it receives from the server when the time is “00:00”, thereby converting it from “00:00” in the server timezone to “00:00” the client one), but I don’t think we’ve ever had a satisfactory solution to this (and I’m not sure if there actually is one).
In the React Form Engine, in an attempt to work around this, it appears we are converting a date selected with a datepicker to a local datetime that would map to 00:00 UTC for that specific date. For instance, if you you are running in EDT and pick a date of May 31st, it converts it to 2023-05-30T20:00:00.000-0400, which would map to 2023-05-31T00:00.000-0000, but it’s unclear to me this will fix things, and specifically it is causing an issue I’ve documented here: [O3-2154] - OpenMRS Issues
I’ll try to dive into this more and and add what I find, but @dkigen @dkayiwa @mksd @mksrom @ddesimone @ibacher @samuel34 @mseaton @burke and others, interested in your take…
Take care, Mark