Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Changed Client-->Server recommendation, improved client-side recommendations. See https://talk.openmrs.org/t/hfe-better-handling-of-timezones/31659/38?u=bistenes

This page details the 3 conventions for handling time zones in OpenMRS on both the client and server sides.

Table of Contents
maxLevel2

Server: Strive to always specify timezone

For historic reasons, the majority of timestamps within the OpenMRS database use MySQL's DATETIME instead of TIMESTAMP , meaning the date & time stored is the local server time, with no associated time zone information. The lack of absolute times causes problems when servers are used across timezones, when client & server are in different timezones, when offset for a location changes (e.g., a server in a location that observes daylight savings time), and when transferring data between servers in different timezones.

...

OpenMRS should evolve toward using absolute times in the database, whether specified as UTC or with an offset.

  • Whenever feasible, any newly created tables should use a datatype that includes timezone (e.g., MySQL's TIMESTAMP, which stores in UTC).
  • When code is being refactored and there's an opportunity to convert from ambiguous times (without timestamp) to absolute times (with timestamp) in the database, we should take them. These changes need to be sensitive not only to how the system behaves going forward, but how the change would affect implementations with existing data.

Ultimately, we'd like to store and use UTC by default within OpenMRS servers/databases; however, we need to work our way there in a way that doesn't put existing implementations (with timezone-less data and assumptions data are not UTC) at risk. 

Server → Client: RFC 3339

The server should send RFC 3339 formatted dates to the client
.
.


The server should send UTC dates formatted as RFC 3339 to the client.  EgRFC 3339 is ISO 8601 with a Z  offset suffix. Eg. "2021-01-29T13:51:03Z" .

It is the responsibility of the server code to translate any date from the server time zone to a string formatted as RFC 3339. There are definitely multiple ways of doing that, for instance using This can be accomplmished in Joda-Time:

Code Block
languagejava
import static org.joda.time.DateTimeZone.UTC;
import org.joda.time.DateTime;
import org.joda.time.format.ISODateTimeFormat;

...

Date date = ..
String rfc3339Date = ISODateTimeFormat.dateTime().print(new DateTime(date.getTime(), UTC));

...

Code Block
languagejava
Date date = ..
StringDateFormat rfc3339Daterfc3339Format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
rfc3339Format.setTimeZone(TimeZone.getTimeZone("UTC"));
String rfc3339Date = rfc3339Format.format(date);

The latter is the approach used by the REST Web Services module, see here.

...

Client → Server:

...

RFC 3339

The client should sent ISO 8601send RFC 3339 formatted dates to the server.

The client should send UTC dates formatted as RFC 3339 to the server that are formatted with ISO 8601 such that date, time and time zone information are always available.
Eg. "2021-01-29T16:51:03+03:00".

TODO: Provide an example on how best to do that in JS

This also means that the server should be ready to parse ISO 8601 formatted dates sent by the client.
See for example how this is done in the REST WS module: https://github.com/openmrs/openmrs-module-webservices.rest/blob/a32a4336c4166153a6769f20c9281645648e70e1/omod-common/src/main/java/org/openmrs/module/webservices/rest/web/ConversionUtil.java#L239-L243

...

. All APIs must be able to parse RFC 3339 dates.

Client Display: In Local

...

Time Zone

The client should display dates in the local time zone of the user.

The client should parse RFC 3339 formatted dates to make it readable and useful to the user. In almost all circumstances users should see dates that are local to them, in accordance to their client or local system's time zone.

This is very straightforward to do in JavaScript as this just works with a RFC 3339 formatted date:If writing client-side code, please familiarize yourself with JavaScript's native support for locale-specific date formatting. Key functions are toLocaleString and its cousins, toLocaleDateString, toLocaleTimeString, and Intl.DateTimeFormat.

Code Block
languagejs
varconst localDatedisplayDate = new Date("2021-01-29T13:51:03Z").toLocaleString();