Time zone changes in Date

# Norbert Lindenberg (11 years ago)

On Jul 19, 2013, at 0:41 , Norbert Lindenberg <ecmascript at lindenbergsoftware.com> wrote:

On Jul 17, 2013, at 20:29 , Brendan Eich <brendan at mozilla.com> wrote:

Norbert Lindenberg wrote:

On Jul 17, 2013, at 13:58 , Brendan Eich<brendan at mozilla.com> wrote:

No, time is stored as milliseconds after the epoch in a number (IEEE double).

A Date object includes position on planet and timezone politics (see getTimezoneOffset).

No, it doesn't. Any time zone information used by getTimeZoneOffset and other non-UTC Date API is based on time zone information in the environment: the "local time zone" is typically what the user has told the OS to use. A Date object itself only wraps the time value.

No. This is not well-specified by ECMA-262, implementations do crack time to date fields in Date instances, and one's timezone can change in a running system (say a Firefox OS phone one takes on a plane).

Implementations are free to cache all kinds of things to improve performance, but they still have to produce the specified behavior. The behavior of Date non-UTC methods is defined in terms of a single time value and conversion functions that rely on local time zone adjustment and local daylight saving time adjustment. The spec text varies a bit between ES5 and ES6, but my interpretation of both would be that when the local time zone changes, the results of LocalTZA, DaylightSavingTA, and LocalTime all change, so caches based on them have to be invalidated.

If some or all implementations have interpreted that differently, then the spec needs to be clarified one way or another.

I did some testing, and found some random behavior in reaction to time zone changes.

The test is here: norbertlindenberg.com/ecmascript/DateTest.html

The test runs for one minute, printing the results of calling toString, getHours, getTimezoneOffset, and (if the Internationalization API is enabled) toLocaleString on two Date instances every 5 seconds. One instance is reused for the entire time; another is created anew each iteration.

For each test run, I manually perform the following steps:

  1. launch the browser while the OS time zone is set to America/Los_Angeles (PDT),
  2. start the test, let it log at least once,
  3. change the operating system's time zone to Europe/Berlin (CEST), let it log at least once,
  4. open a new browser window, let it log at least once,
  5. switch the OS time zone back to PDT, let it log at least once.

Note that toString in Chrome, Firefox, and Safari prints two time zone identifiers, one of the form GMT+/-XXXX, one a more conventional abbreviation. I'll call the first tz1, the second tz2.

At step 2, All browsers display reasonable information about the Date instances in PDT. After that, they all go different paths.

Chrome 28 / Mac (has Internationalization API):

  • At step 3, tz2 for both Date instances changes from PDT to UTC. UTC is not the new time zone, and the only way to change it again to anything other than UTC is by relaunching the browser.
  • Nothing else ever changes.

Firefox Nightly + Internationalization API / Mac:

  • At step 3, tz2 for both Date instances changes from PDT to CEST.
  • At step 4, all remaining output except toLocaleString for both Date instances changes from PDT to CEST.
  • At step 5, tz2 for both Date instances changes back from CEST to PDT.
  • The output of toLocaleString stays in PDT throughout.

Internet Explorer 10 (no Internationalization API):

  • At step 3, all information for new Date instances changes from PDT to CEST (labeled UTC+0200).
  • At step 5, all information for new Date instances changes back from CEST to PDT.

Safari 6.0.5 (no Internationalization API):

  • At step 3, tz2 for the reused Date instance changes from PDT to CEST, and all information for new Date instances changes from PDT to CEST.
  • At step 5, tz2 for the reused Date instance changes back from CEST to PDT, and all information for new Date instances changes back from CEST to PDT.

Bugs as I'd see them:

  • Chrome, Firefox, Safari: The string returned by toString() can contain a tz2 that indicates a time zone that's different from tz1 and doesn't match the time zone assumed for other parts of the string.

  • Firefox: toLocaleString() can use a different time zone than other Date methods.

  • Explorer, Safari: Different Date instances can assume different time zones at the same time.

Norbert