From bb31e854d0a429b53e0ea178af2c554ea986a510 Mon Sep 17 00:00:00 2001 From: Paul Valladares <85648028+dreyfus92@users.noreply.github.com> Date: Mon, 17 Aug 2026 22:39:56 -0600 Subject: [PATCH 1/2] feat(native): add timezone-support to replacements --- docs/modules/timezone-support.md | 89 ++++++++++++++++++++++++++++++++ manifests/native.json | 30 +++++++++++ 2 files changed, 119 insertions(+) create mode 100644 docs/modules/timezone-support.md diff --git a/docs/modules/timezone-support.md b/docs/modules/timezone-support.md new file mode 100644 index 00000000..54c5e7e2 --- /dev/null +++ b/docs/modules/timezone-support.md @@ -0,0 +1,89 @@ +--- +description: Native alternatives to the timezone-support package for listing, resolving and converting time zones +--- + +# Replacements for `timezone-support` + +`timezone-support` ships its own copy of the IANA time zone database and helpers to convert between zones. Modern runtimes already ship this data: `Intl.supportedValuesOf` lists the available zones, and [`Temporal`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal) covers the conversion helpers. + +## `Intl.supportedValuesOf` + +[`Intl.supportedValuesOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/supportedValuesOf) replaces `listTimeZones`: + +```ts +import { listTimeZones } from 'timezone-support' // [!code --] + +const timeZones = listTimeZones() // [!code --] +const timeZones = Intl.supportedValuesOf('timeZone') // [!code ++] +``` + +## `Temporal` + +`findTimeZone` is no longer needed — pass the IANA identifier directly. + +Getting the wall-clock time in a zone (`getZonedTime`, `convertDateToTime`): + +```ts +import { findTimeZone, getZonedTime } from 'timezone-support' // [!code --] + +const date = new Date() +const berlin = findTimeZone('Europe/Berlin') // [!code --] +const time = getZonedTime(date, berlin) // [!code --] +const time = date.toTemporalInstant().toZonedDateTimeISO('Europe/Berlin') // [!code ++] +``` + +Getting the UTC offset (`getUTCOffset`): + +```ts +import { findTimeZone, getUTCOffset } from 'timezone-support' // [!code --] + +const berlin = findTimeZone('Europe/Berlin') // [!code --] +const { offset } = getUTCOffset(new Date(), berlin) // [!code --] +const { offset } = Temporal.Now.zonedDateTimeISO('Europe/Berlin') // [!code ++] +``` + +Note that `Temporal` returns the offset as a string (`'+02:00'`) or via `offsetNanoseconds`, rather than minutes. + +Getting a timestamp or `Date` from a zoned time (`getUnixTime`, `convertTimeToDate`): + + +```ts +import { findTimeZone, getUnixTime } from 'timezone-support' // [!code --] + +const berlin = findTimeZone('Europe/Berlin') // [!code --] +const time = { year: 2018, month: 9, day: 2, hours: 10, minutes: 0 } // [!code --] +const epoch = getUnixTime(time, berlin) // [!code --] +const epoch = Temporal.ZonedDateTime.from({ // [!code ++] + timeZone: 'Europe/Berlin', // [!code ++] + year: 2018, month: 9, day: 2, hour: 10, minute: 0 // [!code ++] +}).epochMilliseconds // [!code ++] + +const date = new Date(epoch) +``` + +Attaching a zone to a wall-clock time (`setTimeZone`): + + +```ts +import { findTimeZone, setTimeZone } from 'timezone-support' // [!code --] + +const berlin = findTimeZone('Europe/Berlin') // [!code --] +const time = { year: 2018, month: 9, day: 2, hours: 10, minutes: 0 } // [!code --] +const berlinTime = setTimeZone(time, berlin) // [!code --] +const berlinTime = Temporal.PlainDateTime // [!code ++] + .from({ year: 2018, month: 9, day: 2, hour: 10, minute: 0 }) // [!code ++] + .toZonedDateTime('Europe/Berlin') // [!code ++] +``` + +Parsing and formatting (`parseZonedTime`, `formatZonedTime`) — `Temporal` parses ISO 8601 strings and `toLocaleString` (backed by `Intl.DateTimeFormat`) handles output; custom format strings such as `'D.M.YYYY H:mm zZ'` are not supported: + + +```ts +import { parseZonedTime, formatZonedTime } from 'timezone-support/parse-format' // [!code --] + +const time = parseZonedTime('2.9.2018 10:00 CEST+02:00', 'D.M.YYYY H:mm zZ') // [!code --] +const time = Temporal.ZonedDateTime.from('2018-09-02T10:00:00+02:00[Europe/Berlin]') // [!code ++] + +const output = formatZonedTime(time, 'D.M.YYYY H:mm zZ') // [!code --] +const output = time.toLocaleString('de-DE', { dateStyle: 'medium', timeStyle: 'short' }) // [!code ++] +``` diff --git a/manifests/native.json b/manifests/native.json index 45a87a3d..f18616b5 100644 --- a/manifests/native.json +++ b/manifests/native.json @@ -759,6 +759,18 @@ "compatKey": "javascript.builtins.Intl.DateTimeFormat.DateTimeFormat" } }, + "Intl.supportedValuesOf": { + "id": "Intl.supportedValuesOf", + "type": "native", + "url": { + "type": "mdn", + "id": "Web/JavaScript/Reference/Global_Objects/Intl/supportedValuesOf" + }, + "webFeatureId": { + "featureId": "intl", + "compatKey": "javascript.builtins.Intl.supportedValuesOf" + } + }, "Iterator": { "id": "Iterator", "type": "native", @@ -1615,6 +1627,18 @@ "compatKey": "javascript.builtins.Symbol.description" } }, + "Temporal": { + "id": "Temporal", + "type": "native", + "url": { + "type": "mdn", + "id": "Web/JavaScript/Reference/Global_Objects/Temporal" + }, + "webFeatureId": { + "featureId": "temporal", + "compatKey": "javascript.builtins.Temporal" + } + }, "TextDecoder": { "id": "TextDecoder", "type": "native", @@ -3416,6 +3440,12 @@ "moduleName": "time-stamp", "replacements": ["Intl.DateTimeFormat"] }, + "timezone-support": { + "type": "module", + "moduleName": "timezone-support", + "replacements": ["Temporal", "Intl.supportedValuesOf"], + "url": {"type": "e18e", "id": "timezone-support"} + }, "to-buffer": { "type": "module", "moduleName": "to-buffer", From bc68ab890d821a3cfe670d33226330b0e6cf6850 Mon Sep 17 00:00:00 2001 From: Paul Valladares <85648028+dreyfus92@users.noreply.github.com> Date: Tue, 18 Aug 2026 13:53:47 -0600 Subject: [PATCH 2/2] Apply suggestions from @43081j's review. --- manifests/native.json | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/manifests/native.json b/manifests/native.json index f18616b5..094230bc 100644 --- a/manifests/native.json +++ b/manifests/native.json @@ -759,18 +759,6 @@ "compatKey": "javascript.builtins.Intl.DateTimeFormat.DateTimeFormat" } }, - "Intl.supportedValuesOf": { - "id": "Intl.supportedValuesOf", - "type": "native", - "url": { - "type": "mdn", - "id": "Web/JavaScript/Reference/Global_Objects/Intl/supportedValuesOf" - }, - "webFeatureId": { - "featureId": "intl", - "compatKey": "javascript.builtins.Intl.supportedValuesOf" - } - }, "Iterator": { "id": "Iterator", "type": "native", @@ -3443,7 +3431,7 @@ "timezone-support": { "type": "module", "moduleName": "timezone-support", - "replacements": ["Temporal", "Intl.supportedValuesOf"], + "replacements": ["Temporal"], "url": {"type": "e18e", "id": "timezone-support"} }, "to-buffer": {