temporal-polyfill: `Temporal.Now.timeZoneId()` returns `undefined` on MacOS 14.0 (Sonoma)

As the title suggests I am getting `undefined when running this code

Temporal.Now.timeZoneId() // undefined

Not sure what other information I need to provide however here is the output of npx envinfo --system --binaries --browsers

  System:
    OS: macOS 14.0
    CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
    Memory: 410.13 MB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 18.17.0 - ~/.nvm/versions/node/v18.17.0/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v18.17.0/bin/yarn
    npm: 9.6.7 - ~/.nvm/versions/node/v18.17.0/bin/npm
    pnpm: 8.6.11 - ~/.nvm/versions/node/v18.17.0/bin/pnpm
  Browsers:
    Chrome: 117.0.5938.149
    Safari: 17.0

About this issue

  • Original URL
  • State: closed
  • Created 9 months ago
  • Comments: 18 (9 by maintainers)

Most upvoted comments

Firefox is also using ICU, so we had the same time zone bug on Sonoma as Chrome had. We’ve integrated the ICU patch in https://bugzilla.mozilla.org/show_bug.cgi?id=1856428 for all release branches, so the next Firefox release (October 24, 2023) will work correctly again.


Etc/GMT-8 was returned in Firefox, because we have a fallback code path to handle the case when ICU isn’t able to determine the system time zone. Basically when ICU reports back that it can’t determine the system time zone, we try to give the user a better time zone than just UTC.

This is a known bug in Chromium on MacOS 14.0: https://bugs.chromium.org/p/chromium/issues/detail?id=1487920

Other related Chromium issues:

It’s not related to the Temporal polyfill. The underlying API that the polyfill uses is also affected. Example:

new Intl.DateTimeFormat().resolvedOptions().timeZone

To add to that when I try to use Temporal.Now.zonedDateTimeISO() I get the following error

RangeError: Invalid time zone specified: undefined

why are we using Epoch for canonical comparisons?

The canonicalEquals example you linked to comes from https://github.com/tc39/proposal-canonical-tz#6-add-temporaltimezoneprototypeequals, which demonstrated that comparing time zones for equality was possible using the ZonedDateTime.prototype.equals method. A ZonedDateTime instance stores three pieces of data: an Instant (number of nanoseconds since epoch), a time zone, and a calendar. By using the same instant and calendar when creating two ZonedDateTime instances, you can use ZonedDateTime.prototype.equals to determine whether two time zones are equal.

Epoch could have been any other time, the key was that they are equal.

Modern code can use the new Temporal.TimeZone.prototype.equals method instead, for a more ergonomic comparison. Like this:

Temporal.TimeZone.from('Asia/Calcutta').equals('Asia/Kolkata'); // => true
Temporal.TimeZone.from('Asia/Calcutta').equals('Asia/Colombo'); // => false

I updated my comment above to link to a more appropriate Chromium issue, and added some related links.

Is there any sensible workaround this?

If yours is a server app running in Node, you could I guess try running it in Bun, which uses Safari’s JS engine JavaScriptCore which doesn’t exhibit this problem.

For client apps, the only workaround seems to be using Firefox or Safari.

But I don’t think there’s any way to work around this in V8, so any V8-based host (Chrome, Node, etc.) will have the problem.