Intl.DateTimeFormat vs. Temporal.ZonedDateTime for DST-Safe Time Zone Conversion in TypeScript
0 reputation · 03 Aug 2022, 02:19 UTC
TypeScript's lib adds no time zone abstraction to Date — methods like getHours and toISOString use only the host zone or UTC — so regional conversion comes down to two documented paths: built-in Intl.DateTimeFormat with its timeZone option, or the Stage 3 Temporal.ZonedDateTime reached through the @js-temporal/polyfill and its shipped type declarations.
The constraint is DST-safe day arithmetic. A Date stores only a UTC instant, so shifting a scheduled time by one day in a target zone means re-formatting through Intl after each mutation to recover the correct wall clock. Temporal.ZonedDateTime.add({ days: 1 }) applies the zone's rules directly instead.
Neither path checks zone identifiers at compile time. Intl.DateTimeFormatOptions.timeZone is typed as plain string, so a misspelled IANA name such as 'Asia/Kolkatta' passes strict compilation and, per ECMA-402, only surfaces as a RangeError when the formatter is constructed. The polyfill's declarations accept the same stringly-typed identifiers.
Given that, which path is the sounder default for regional scheduling logic while Temporal remains Stage 3 and outside the default lib? Is a user-level branded IanaZone type with a runtime allowlist worth layering onto either choice to catch typos before deployment? And do runtime ICU/tzdata differences in alias handling shift the comparison?