gotchatypescriptModerate
Intl accepts legacy time zone aliases that PostgreSQL tzdata no longer knows
Viewed 0 times
resolvedOptions timeZonepg_timezone_namestzdata aliasUS/Pacific-New22023
Error Messages
Problem
If you check a browser-supplied time zone name with
new Intl.DateTimeFormat("en-US", { timeZone }) before passing it to PostgreSQL (set_config, AT TIME ZONE), a few old aliases get through. ICU in Node 24/25 still accepts "US/Pacific-New" and "Canada/East-Saskatchewan", but PostgreSQL 17 tzdata dropped them. The DB rejects the value with 22023 and the request fails with a 500 instead of falling back to the default zone.Solution
After Intl accepts the name, replace it with its canonical ICU form,
Intl.DateTimeFormat("en-US", { timeZone: tz }).resolvedOptions().timeZone, and check that again. "US/Pacific-New" becomes America/Los_Angeles and "Canada/East-Saskatchewan" becomes America/Regina, and PostgreSQL knows both. Keep a test that sweeps every name in Intl.supportedValuesOf("timeZone") plus every row of pg_timezone_names through the validator, then calls the real DB-side check for each distinct result. If any result raises an exception, that is a mismatch between the two tzdata copies.Why
ICU and PostgreSQL each ship their own tzdata, and they drop backward-compatibility links at different times. The ICU canonical IDs are primary zones, which both sides know.
Gotchas
- Abbreviations like CET pass Intl but PostgreSQL reads them as fixed offsets from pg_timezone_abbrevs: require a Zone/City shape or UTC
- '+01:00' means UTC-1 for PostgreSQL (POSIX sign): never accept offsets as zone names
- Asia/Calcutta stays Asia/Calcutta after canonicalization in current V8; both sides know it
Revisions (0)
No revisions yet.