Skip to content

Timezone Notes

Ryan Slominski edited this page Jun 22, 2023 · 20 revisions

Overview

MYA time data is stored in MariaDB as numeric values (bigint type) and consist of modified UNIX timetamps (36-bit instead of standard 32-bit to address year 2038 issue, plus each timestamp also has 28 bits of fractional seconds), so in UTC. Generally timestamp literals are provided by the user as a string with implied timezone "America/New_York". When using the mycontainer functions str_to_mya() and mya_to_str() MariaDB relies on the System Timezone (unless explictly overridden with session timezone or the like) when the functions use the unix_timestamp() and from_unixtime() and the System Timezone generally should be set to "America/New_York", often using the TZ environment variable. Note that containers generally default to UTC as the System Timezone.

JMYAPI has a toLocalDT() function that uses the System Timezone as well. Generally this should be set to "America/New_York" as well, and should match mycontainer. JMYAPI generally fetches MYA timestamps as is, then provides utilities to convert them to Java Instants, which are basically fancy Unix Timestamps that can easily be formatted as user friendly date strings.

The myquery app leverages jmyapi, so the myquery container System Timezone should match mycontainer and generally should be "America/New_York".

Timezone handling in Browsers

Historically time zone handling in browsers has been terrible. The browser provided JavaScript Date API is aware of it's current local time and offset, but not necessarily the full zone rules (database/history of rules), so no reliable cross-browser mechanism to figure out what was or would be, even in the local zone. Recently it's improved, but still is bad. The toLocaleDate() method wraps a new Intl obj to allow converting from a Date to a String formatted in a different time zone. However, you still can't create a new Date object and specify the time zone, it's always assumed browser local time (or optionally UTC). Apparently there are more efforts on the way, such as the Temporal API. In the meantime we still must resort to workarounds in some cases, such as when a user provides a date and time as input and we need to interpret it as a timestamp in America/New_York zone, even if the user's browser is in say America/Santiago. In this case in order to convert the user provided string to a Date we must either ask the server to do it, or use a third party library. The Date object stores time as an offset from the 1970 Epoch, like a UNIX timestamp, but in milliseconds. Third party libraries often provide an alternative object with methods to convert between their own object and Date and either bring along their own copy of the IANA database, else abuse the new Intl API. Wait, what! (how?).

Timezone handling in CanvasJS

We use the CanvasJS charting library, but it's support for time zones is limited in the same way as browsers. We use the dateTime setting for the x axis such that we can leverage tick (grid line) generation controls such as interval and intervalType. We actually calculate the appropriate interval (count) and type ourselves based on chart zoom, but use the CanvasJS interval API that allows us the flexibility to specify it. The main tool to support time zones is the ability to format labels.

Testing

In order to test the use case of a user traveling to another country and then wanted to view archiver data, we need to be able to run a test web browser in a container or virtual machine that has the timezone set to something other than "America/New_York", for example with TZ=America/Santiago. The most straight forward is to simply spin up a test container with alternate timezone, launch firefox from within the container, and then forward the display via X-Windows. This is especially straight forward if developing on a Linux host as they already have a built-in X-Server. On Windows you need to install an X-Server.

Alternatively, if developing on Windows it turns out there is a new way (as of Jan 2023) in which Windows sets up a RDP connection with WSL2 and forwards the Linux display (specific window) to the local Windows host via RDP. Inside WSL2 Ubuntu bash for example you can sudo apt install firefox, export TZ=America/Santiago, then launch firefox and navigate to WAVE. If your developer workstation doesn't have a DNS entry (e.g. a laptop or home desktop), you can leverage the host's <hostname>.local format to reference a wave running on the localhost (localhost won't work inside WSL2). You can also launch a container from within WSL2 that can then put displays on the local Windows desktop - a GUI container.

See Also

Clone this wiki locally