HFE: Better handling of timezones

Fully agree.

I think being specific is the best (i.e., have it fully qualified with an offset relative to UTC / or Z for UTC), but otherwise a convention (if consistent) would work, too.

Yeah, there’s really no reason we could want to send or store a timestamp that isn’t UTC. UTC is perfectly unambiguous, and reliably localized by client-side technologies.

Timestamps with offsets are supported by ISO-8601 (e.g. 2020-01-19T09:23:00-08:00) but are actually totally equivalent to UTC-stamped equivalents—they represent an unambiguous moment in time, but are still ambiguous to place because time zones may have different offsets through out the year (due to DST etc). Therefore they don’t add any useful information beyond what UTC provides.

@burke : If the override GP was set to a non-UTC timezone OR a request to the server supported specifying a timezone (e.g., the client said give me timestamps in EAT and the server honored it), then server responses could be in a non-UTC timezone in some cases.

What’s the expected behavior, from the user’s perspective?

A timestamp that includes an explicit timestamp is unambiguous. A timestamp without a timezone – even if the timestamp used is UTC – is still ambiguous if the code using it doesn’t know its UTC.

I would think 99% of use cases, people would not want to think about or see timezones (just assume times are in their local timezone). The exceptions would be implementations that work across timezones or where daylight savings time is observed (timezone becomes critically important for inpatient care across DST changes).

@mksd, thank you for documenting Timezone Conventions for the community. I’ve made some minor edits (primarily just including conventions for server/database).

My understanding is ISO 8601 describes how all dates & times should be represented in the world and RFC 3339 defines how the rules of ISO 8601 should be applied to internet communications. So, Server → Client traffic using RFC 3339 makes sense; however, you suggest Client → Server traffic should use ISO 8601 (not necessarily following RFC 3339’s interpretation of ISO 8601). Is there a reason clients should not use RFC 3339 when communicating to the server? Is this because our REST/FHIR APIs don’t currently follow RFC 3339 when receiving data from clients?

So @bistenes asked the exact same question here on Slack. Yes I think it makes sense to enforce RFC 3339 everywhere. It’s just that REST WS doesn’t require this and hence, as long as it’s ISO 8601 it’s fine anyway. In other words, we don’t have to be as restrictive as RFC 3339 in the client → server direction.


Also in HFE (actually through the ticket HTML-755 discussed on this thread) we have a funny case where the date info is sent to the server as three separate pieces: date + time + timezone. Why? Because of an ancient widget used behind <encounterDate/> that predates the nice modern date-time pickers.

Anyway, the point is that in that case it is easier to just wire “as is” what was selected on the client side by sending those three pieces. One of the pieces being the client timezone. That’s not even ISO 8601 btw, but that’s the spirit of ISO 8601.


P.S. Question to the anglophones out there, does one write “time zone” or “timezone” in plain English?

The goal of conventions is not to make unbreakable rules; rather, to define & promote best (preferred) practice and make it easier to identify when we are breaking our conventions (so we have to justify breaking them). Given this, how about promoting RFC 3339 for all internet traffic? If REST WS accepts some forms that meet ISO 8601 but not RFC 3339, that’s fine, but we don’t need to promote adding new cases like this.

This is not surprising given the number of years we’ve been coding. If things didn’t change, they could never get better. :slight_smile:

Ah. You taught me something. The “timezone” compound is currently used primarily in the US. So, I’ll learn to make space for time zone for now… but I think anglophones might agree “timezone” is on the roadmap. :wink:

That’s interesting. I always thought it was a “technologism”, i.e., a word used in the context of programming, maybe as a result of writing too many functions named getTimeZone(). In more formal writing contexts, I’ve only ever seen “time zone”.

2 Likes

@burke sounds good, I’ll update the wiki page accordingly later this week.

So after exchanging with @dkayiwa, we are heading to introduce a new org.openmrs.util.TimeZoneUtil (see its basic form here staged in HFE.)

(Q) The naming question is: TimeZoneUtil or TimezoneUtil? :wink:

I’d vote for TimeZoneUtil (I think it fits better with the java.time naming conventions in my mind, e.g. ZonedDateTime, ZoneId, etc.).

2 Likes

I just did a Google search for TimezoneUtil and 99.9% of the results are TimeZoneUtil :smile:

2 Likes

Until it goes the way of “roadmap”, “time zone” is two words, so the “Z” should be capitalized.

I hope that’s a fair characterization… er, characterisation. :wink:

@dkayiwa do we have a ticket for this ? Or i carve one befitting it ?

@tendomart for what? Centralising the timezone utils class into Core, and deprecating that class in various modules where’s it’s been copied over? If so, no I don’t think there’s a ticket for that.

Thanks @mksd was doing some house cleaning for the Technical Roadmap - Documentation - OpenMRS Wiki

There’s an epic for everything related to supporting timezones in the Ref App, that’s RA-1906. Is that what you’re looking for?

I guess so , but i think it most of the Tickets belong to Refapp with exception of RESTWS-644

So due to this PR about serverDate I’ve come back to this Talk thread.

Reading through the comments here and the Time Zones Conventions document, I think it needs to be pointed out that offsets are not time zones. -08:00 is an offset. America/Los Angeles is a timezone, which is sometimes -08:00 and sometimes -07:00.

@mksd I recommend amending the “Client → Server” section of that document. There are three reasonable options:

  1. Send RFC 3339 times Client → Server
  2. Explain why it is useful for the server to receive the client’s offset
  3. Define an ISO + TZ format we should use

As an aside, I’d recommend changing the example in “Client Display: In Local Time Zone” to something like

const displayDate = new Date("2021-01-29T13:51:03Z").toLocaleString();

or

const displayDate = new Date("2021-01-29T13:51:03Z").toLocaleString("es-MX");

Ping @mksd @jfigueiredo @burke @ibacher .

About that offset, it could not always be the same, but normally that is not a problem, because we dont hardcode that value… we could use JS with.toISOString() to format it to ISO8601 format.

Example: new Date().toISOString();

Output is 2021-09-21T16:34:58.232Z, we don’t touch in the offset manually.

So, I agree that we could remove that offset part that could be confusing and put this example when we are doing Client -> Server.