@northguild/gmt 1.14.2 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/README.md +43 -13
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.js +1 -0
  4. package/dist/plain/calculate/diffDateAsDuration.js +1 -1
  5. package/dist/plain/calculate/index.d.ts +2 -1
  6. package/dist/plain/calculate/index.js +2 -1
  7. package/dist/plain/calculate/{weekOfYear.d.ts → weekOfYearForDate.d.ts} +0 -14
  8. package/dist/plain/calculate/weekOfYearForDate.js +28 -0
  9. package/dist/plain/calculate/weekOfYearForDateTime.d.ts +14 -0
  10. package/dist/plain/calculate/{weekOfYear.js → weekOfYearForDateTime.js} +1 -27
  11. package/dist/plain/format/formatCalendar.d.ts +2 -2
  12. package/dist/plain/format/formatDate.d.ts +3 -2
  13. package/dist/plain/format/formatDate.js +1 -1
  14. package/dist/plain/format/formatDateRange.d.ts +3 -2
  15. package/dist/plain/format/formatDateRange.js +1 -1
  16. package/dist/plain/format/formatDateTime.d.ts +3 -2
  17. package/dist/plain/format/formatDateTime.js +1 -1
  18. package/dist/plain/format/formatDateTimeRange.d.ts +3 -2
  19. package/dist/plain/format/formatDateTimeRange.js +1 -1
  20. package/dist/plain/format/formatDateTimeToParts.d.ts +3 -2
  21. package/dist/plain/format/formatDateTimeToParts.js +1 -1
  22. package/dist/plain/format/formatDateToParts.d.ts +3 -2
  23. package/dist/plain/format/formatDateToParts.js +1 -1
  24. package/dist/plain/format/formatRelativeDate.d.ts +3 -14
  25. package/dist/plain/format/formatRelativeDateTime.d.ts +3 -14
  26. package/dist/plain/format/formatRelativeTime.d.ts +3 -14
  27. package/dist/plain/format/formatTime.d.ts +2 -1
  28. package/dist/plain/get/getNowUnit.d.ts +2 -3
  29. package/dist/plain/interval/splitIntervalByUnitDate.js +1 -1
  30. package/dist/regex/calendar-date.d.ts +19 -0
  31. package/dist/regex/calendar-date.js +19 -10
  32. package/dist/regex/calendar-zoned-date-time.d.ts +45 -0
  33. package/dist/regex/calendar-zoned-date-time.js +45 -40
  34. package/dist/regex/date-time.d.ts +18 -0
  35. package/dist/regex/date-time.js +18 -1
  36. package/dist/regex/date.d.ts +16 -0
  37. package/dist/regex/date.js +16 -1
  38. package/dist/regex/http-date.d.ts +15 -0
  39. package/dist/regex/http-date.js +15 -6
  40. package/dist/regex/leap-second.d.ts +12 -0
  41. package/dist/regex/leap-second.js +12 -1
  42. package/dist/regex/rfc-2822.d.ts +18 -0
  43. package/dist/regex/rfc-2822.js +18 -8
  44. package/dist/regex/rfc-3339.d.ts +19 -0
  45. package/dist/regex/rfc-3339.js +19 -6
  46. package/dist/regex/sql-date-time.d.ts +14 -0
  47. package/dist/regex/sql-date-time.js +14 -6
  48. package/dist/regex/time-zone-like.d.ts +21 -0
  49. package/dist/regex/time-zone-like.js +21 -0
  50. package/dist/regex/time.d.ts +59 -0
  51. package/dist/regex/time.js +59 -3
  52. package/dist/regex/unix.d.ts +21 -0
  53. package/dist/regex/unix.js +21 -0
  54. package/dist/regex/utc-date-time.d.ts +20 -0
  55. package/dist/regex/utc-date-time.js +20 -1
  56. package/dist/types/calendar-options.d.ts +11 -0
  57. package/dist/types/calendar-options.js +0 -0
  58. package/dist/types/datetime-format-options.d.ts +6 -0
  59. package/dist/types/datetime-format-options.js +0 -0
  60. package/dist/types/duration-unit.d.ts +5 -0
  61. package/dist/types/duration-unit.js +0 -0
  62. package/dist/types/index.d.ts +11 -0
  63. package/dist/types/index.js +11 -0
  64. package/dist/types/now-unit.d.ts +5 -0
  65. package/dist/types/now-unit.js +0 -0
  66. package/dist/types/relative-date-time-unit.d.ts +6 -0
  67. package/dist/types/relative-date-time-unit.js +0 -0
  68. package/dist/types/relative-date-unit.d.ts +5 -0
  69. package/dist/types/relative-date-unit.js +0 -0
  70. package/dist/types/relative-time-options.d.ts +18 -0
  71. package/dist/types/relative-time-options.js +0 -0
  72. package/dist/types/relative-time-unit.d.ts +5 -0
  73. package/dist/types/relative-time-unit.js +0 -0
  74. package/dist/types/relative-unit.d.ts +6 -0
  75. package/dist/types/relative-unit.js +0 -0
  76. package/dist/types/unix-now-unit.d.ts +5 -0
  77. package/dist/types/unix-now-unit.js +0 -0
  78. package/dist/types/utc-now-unit.d.ts +5 -0
  79. package/dist/types/utc-now-unit.js +0 -0
  80. package/dist/unix/calculate/startOrEndOfUnix.d.ts +18 -0
  81. package/dist/unix/calculate/startOrEndOfUnix.js +18 -0
  82. package/dist/unix/format/formatCalendarUnix.d.ts +27 -1
  83. package/dist/unix/format/formatRelativeUnix.d.ts +1 -8
  84. package/dist/unix/format/formatUnix.d.ts +19 -0
  85. package/dist/unix/format/formatUnix.js +19 -0
  86. package/dist/unix/get/getUnixNowUnit.d.ts +2 -3
  87. package/dist/unix/parse/parseUnitFromUnix.d.ts +24 -0
  88. package/dist/unix/validate/isValidUnixUnit.d.ts +15 -0
  89. package/dist/utc/calculate/startOrEndOfUtc.d.ts +17 -0
  90. package/dist/utc/calculate/startOrEndOfUtc.js +17 -0
  91. package/dist/utc/format/formatCalendarUtc.d.ts +2 -2
  92. package/dist/utc/format/formatRelativeUtc.d.ts +2 -12
  93. package/dist/utc/format/formatUtc.d.ts +33 -0
  94. package/dist/utc/format/formatUtc.js +17 -0
  95. package/dist/utc/get/getUtcNowUnit.d.ts +2 -3
  96. package/dist/utc/parse/parseUnitFromUtc.d.ts +23 -0
  97. package/dist/zoned/format/formatRelativeZoned.d.ts +1 -8
  98. package/dist/zoned/format/formatTimeZoneName.d.ts +15 -0
  99. package/dist/zoned/format/formatZonedDateTime.d.ts +2 -1
  100. package/dist/zoned/format/formatZonedRange.d.ts +2 -1
  101. package/dist/zoned/format/formatZonedToParts.d.ts +2 -1
  102. package/dist/zoned/get/getDstTransitions.d.ts +18 -2
  103. package/dist/zoned/get/getZonedNowUnit.d.ts +24 -0
  104. package/dist/zoned/interval/intervalDifferenceZoned.d.ts +3 -3
  105. package/dist/zoned/interval/intervalDifferenceZoned.js +3 -3
  106. package/dist/zoned/interval/intervalXorZoned.d.ts +6 -4
  107. package/dist/zoned/interval/intervalXorZoned.js +6 -4
  108. package/dist/zoned/parse/getZonedOffsetAs.d.ts +11 -0
  109. package/dist/zoned/parse/parseUnitFromZoned.d.ts +24 -0
  110. package/package.json +25 -7
  111. package/skills/gmt-arithmetic/SKILL.md +83 -0
  112. package/skills/gmt-basics/SKILL.md +80 -0
  113. package/skills/gmt-integration/SKILL.md +73 -0
  114. package/skills/gmt-timezone/SKILL.md +80 -0
  115. package/skills/_artifacts/domain_map.yaml +0 -547
  116. package/skills/_artifacts/skill_spec.md +0 -67
  117. package/skills/_artifacts/skill_tree.yaml +0 -278
  118. package/skills/api-expansion-workflow/SKILL.md +0 -52
  119. package/skills/app-integration/SKILL.md +0 -38
  120. package/skills/calculate-dates/SKILL.md +0 -432
  121. package/skills/compare-dates/SKILL.md +0 -412
  122. package/skills/convert-types/SKILL.md +0 -305
  123. package/skills/durations/SKILL.md +0 -418
  124. package/skills/format-date-time/SKILL.md +0 -486
  125. package/skills/format-date-time/references/format-api.md +0 -34
  126. package/skills/format-relative-time/SKILL.md +0 -223
  127. package/skills/get-current/SKILL.md +0 -229
  128. package/skills/interval-ops/SKILL.md +0 -432
  129. package/skills/issue-creation/SKILL.md +0 -118
  130. package/skills/lint-package-suggestion/SKILL.md +0 -37
  131. package/skills/new-method-implementation/SKILL.md +0 -71
  132. package/skills/parse-date-time/SKILL.md +0 -349
  133. package/skills/pr-contribution/SKILL.md +0 -180
  134. package/skills/unit-test-generation/SKILL.md +0 -56
  135. package/skills/validate-dates/SKILL.md +0 -438
  136. package/skills/zoned-date-ops/SKILL.md +0 -422
  137. package/skills/zoned-date-ops/references/timezones.md +0 -13
@@ -1,422 +0,0 @@
1
- ---
2
- name: zoned-date-ops
3
- description: >
4
- Work with timezone-aware dates and times using IANA timezone identifiers. Use
5
- getZonedNow, formatZonedDateTime, formatZonedRange, formatRelativeZoned,
6
- getSystemTimeZone, getTimeZones for basics. Use convertPlainDateTimeToZoned,
7
- addZoned, subtractZoned, startOfZoned, endOfZoned, startOfQuarterForZoned,
8
- endOfQuarterForZoned, mapZonedHoursInDay, getLocaleZonedStartOfWeek,
9
- getLocaleZonedEndOfWeek, clampZoned, closestZonedTo, getHoursInZonedDay,
10
- setZoned, setUnix, setUtc, cycleZoned for DST-aware construction, arithmetic,
11
- boundaries, locale-week, day-length, field setting, and field cycling (wrap,
12
- don't carry into the next field). Most accept disambiguation ("compatible" |
13
- "earlier" | "later" | "reject") for gap/overlap resolution; boundary, set*,
14
- and cycleZoned also accept offset ("prefer" | "use" | "ignore" | "reject",
15
- default "ignore"). Use getZonedOffset, getZonedOffsetAs, getTimeZoneOffset,
16
- formatTimeZoneName, isInDaylightSaving for reading a zoned value's UTC offset
17
- and DST status.
18
- sources:
19
- - 'northguild/gmt:packages/gmt/src/zoned/get/index.ts'
20
- - 'northguild/gmt:packages/gmt/src/zoned/format/index.ts'
21
- - 'northguild/gmt:packages/gmt/src/zoned/validate/index.ts'
22
- - 'northguild/gmt:packages/gmt/src/zoned/parse/getZonedOffset.ts'
23
- - 'northguild/gmt:packages/gmt/src/zoned/parse/getZonedOffsetAs.ts'
24
- - 'northguild/gmt:packages/gmt/src/zoned/compare/isInDaylightSaving.ts'
25
- - 'northguild/gmt:packages/gmt/src/zoned/convert/index.ts'
26
- - 'northguild/gmt:packages/gmt/src/zoned/convert/convertZonedToCalendar.ts'
27
- - 'northguild/gmt:packages/gmt/src/zoned/calculate/addZoned.ts'
28
- - 'northguild/gmt:packages/gmt/src/zoned/calculate/subtractZoned.ts'
29
- - 'northguild/gmt:packages/gmt/src/zoned/calculate/startOfZoned.ts'
30
- - 'northguild/gmt:packages/gmt/src/zoned/calculate/endOfZoned.ts'
31
- - 'northguild/gmt:packages/gmt/src/zoned/calculate/startOfQuarterForZoned.ts'
32
- - 'northguild/gmt:packages/gmt/src/zoned/calculate/endOfQuarterForZoned.ts'
33
- - 'northguild/gmt:packages/gmt/src/zoned/calculate/getLocaleZonedStartOfWeek.ts'
34
- - 'northguild/gmt:packages/gmt/src/zoned/calculate/getLocaleZonedEndOfWeek.ts'
35
- - 'northguild/gmt:packages/gmt/src/zoned/calculate/clampZoned.ts'
36
- - 'northguild/gmt:packages/gmt/src/zoned/calculate/closestZonedTo.ts'
37
- - 'northguild/gmt:packages/gmt/src/zoned/calculate/getHoursInZonedDay.ts'
38
- - 'northguild/gmt:packages/gmt/src/zoned/map/mapZonedHoursInDay.ts'
39
- - 'northguild/gmt:packages/gmt/src/unix/calculate/startOfUnix.ts'
40
- - 'northguild/gmt:packages/gmt/src/unix/calculate/endOfUnix.ts'
41
- - 'northguild/gmt:packages/gmt/src/unix/calculate/startOfQuarterForUnix.ts'
42
- - 'northguild/gmt:packages/gmt/src/unix/calculate/endOfQuarterForUnix.ts'
43
- - 'northguild/gmt:packages/gmt/src/zoned/calculate/setZoned.ts'
44
- - 'northguild/gmt:packages/gmt/src/unix/calculate/setUnix.ts'
45
- - 'northguild/gmt:packages/gmt/src/utc/calculate/setUtc.ts'
46
- - 'northguild/gmt:packages/gmt/src/zoned/calculate/cycleZoned.ts'
47
- metadata:
48
- type: core
49
- library: '@northguild/gmt'
50
- library_version: '1.14.2'
51
- ---
52
-
53
- # Zoned Date Operations
54
-
55
- Use this skill when you need timezone-aware date/time operations.
56
-
57
- ## Setup
58
-
59
- ```ts
60
- import {
61
- getZonedNow, getZonedToday, getSystemTimeZone, getTimeZones,
62
- isValidTimeZone, formatZonedDateTime, formatZonedRange, formatRelativeZoned,
63
- convertPlainDateTimeToZoned, addZoned, subtractZoned,
64
- startOfZoned, endOfZoned, startOfQuarterForZoned, endOfQuarterForZoned,
65
- getLocaleZonedStartOfWeek, getLocaleZonedEndOfWeek,
66
- clampZoned, closestZonedTo, mapZonedHoursInDay, getHoursInZonedDay,
67
- setZoned, getZonedOffset, getZonedOffsetAs, getTimeZoneOffset,
68
- formatTimeZoneName, isInDaylightSaving
69
- } from "@northguild/gmt/zoned";
70
- ```
71
-
72
- ## Core Patterns
73
-
74
- ### Get current time in a timezone
75
-
76
- ```ts
77
- const now = getZonedNow("America/New_York"); // "2024-03-15T10:30:45"
78
- const today = getZonedToday("America/New_York"); // "2024-03-15"
79
- ```
80
-
81
- ### Format zoned datetime
82
-
83
- ```ts
84
- formatZonedDateTime("2024-03-15T14:30:45[America/New_York]", "en-US");
85
- // "3/15/2024, 10:30:45 AM"
86
- ```
87
-
88
- ### Format zoned range
89
-
90
- ```ts
91
- const from = "2024-02-29T10:00:00-05:00[America/New_York]";
92
- const to = "2024-02-29T12:00:00-05:00[America/New_York]";
93
- formatZonedRange(from, to, "en-US", { dateStyle: "long", timeStyle: "short" });
94
- // "February 29, 2024, 10:00 AM – 12:00 PM"
95
- ```
96
-
97
- > Both endpoints must share the same IANA timezone. Mismatched zones return `""`.
98
-
99
- ### Format relative zoned datetime (DST-safe)
100
-
101
- ```ts
102
- const value = "2024-03-15T10:00:00-05:00[America/New_York]";
103
- const reference = "2024-03-15T12:00:00-05:00[America/New_York]";
104
- formatRelativeZoned(value, "en-US", { reference }); // "2 hours ago"
105
- ```
106
-
107
- `formatRelativeZoned` computes the diff via `Temporal.ZonedDateTime` arithmetic, so it correctly handles DST transitions.
108
-
109
- ### Validate and parse timezone
110
-
111
- ```ts
112
- isValidTimeZone("America/New_York"); // true
113
- parseTimezoneFromZoned("2024-03-15T14:30:45[America/New_York]"); // "America/New_York"
114
- ```
115
-
116
- ### Get zoned date components
117
-
118
- ```ts
119
- const zoned = "2024-03-15T14:30:45[America/New_York]";
120
- getYear(zoned); // 2024
121
- getMonth(zoned); // 3
122
- getDay(zoned); // 15
123
- ```
124
-
125
- ### Convert plain datetime to zoned (with DST disambiguation)
126
-
127
- ```ts
128
- convertPlainDateTimeToZoned("2024-03-15T14:30:45", "America/New_York");
129
- // "2024-03-15T14:30:45.000-04:00[America/New_York]"
130
- ```
131
-
132
- Pass `disambiguation` to control gap/overlap resolution: `"compatible"` (default), `"earlier"`, `"later"`, or `"reject"`. See [DST Disambiguation](../../../../docs/dst-disambiguation.md).
133
-
134
- ### Add/subtract duration from zoned datetime
135
-
136
- ```ts
137
- addZoned("2024-03-15T14:30:45[America/New_York]", { days: 1 });
138
- // "2024-03-16T14:30:45-04:00[America/New_York]"
139
- ```
140
-
141
- Same `disambiguation` option, but it only affects fall-back overlaps — it has **no effect** on spring-forward gaps. See [DST Disambiguation](../../../../docs/dst-disambiguation.md#which-function-do-i-actually-need).
142
-
143
- ### Jump to boundary (start/end of unit, quarter, hours-in-day)
144
-
145
- ```ts
146
- startOfZoned("2024-03-15T14:30:45[America/New_York]", "month");
147
- // "2024-03-01T00:00:00-05:00[America/New_York]"
148
-
149
- endOfZoned("2024-03-15T14:30:45[America/New_York]", "hour");
150
- // "2024-03-15T14:59:59.999999999-04:00[America/New_York]"
151
- ```
152
-
153
- These accept `disambiguation` (full gap/overlap control) and `offset` (`"prefer" | "use" | "ignore" | "reject"`, default `"ignore"`). Leave `offset` at default unless you deliberately need Temporal's raw `.with()` semantics. See [The offset parameter](../../../../docs/dst-disambiguation.md#the-offset-parameter).
154
-
155
- ### Set one or more fields directly
156
-
157
- ```ts
158
- setZoned("2024-03-15T14:30:45[America/New_York]", { hour: 9 });
159
- // "2024-03-15T09:30:45-04:00[America/New_York]"
160
-
161
- setZoned(
162
- "2024-11-03T01:45:00-05:00[America/New_York]",
163
- { minute: 0 },
164
- { disambiguation: "reject" },
165
- );
166
- // "" — offset defaults to "ignore" so disambiguation actually fires on this fall-back overlap
167
- ```
168
-
169
- `setZoned`/`setUnix`/`setUtc` wrap `Temporal.ZonedDateTime.prototype.with()`, resolving every supplied field in a single atomic overflow pass — the safe alternative to composing `addZoned()`/`addUnix()`/`addUtc()` calls field-by-field, and the only construction path that can reproduce `startOfZoned`'s disambiguation-plus-offset handling (`addZoned()` has no `offset` control equivalent, because `ZonedDateTime.prototype.add()` doesn't accept `disambiguation`/`offset` at all). They accept `disambiguation`, `offset` (default `"ignore"`, same rule as the `startOfZoned` family), and `overflow` (real effect here, since fields are caller-supplied rather than fixed literals). `setUtc`'s `disambiguation`/`offset` are accepted for signature consistency but are permanently inert — `"UTC"` has no DST transitions.
170
-
171
- ### Cycle (wrap) a single field instead of setting it directly (E6)
172
-
173
- ```ts
174
- import { cycleZoned } from "@northguild/gmt";
175
-
176
- cycleZoned("2024-12-15T09:30:00-06:00[America/Chicago]", "month", 1);
177
- // "2024-01-15T09:30:00-06:00[America/Chicago]" — wraps, stays in the same year
178
-
179
- cycleZoned("2024-03-10T01:30:00-06:00[America/Chicago]", "hour", 1);
180
- // "2024-03-10T03:30:00-05:00[America/Chicago]" — cycled hour lands in a spring-forward
181
- // gap; disambiguation ("compatible" by default) resolves it the same way setZoned does
182
-
183
- cycleZoned(
184
- "2024-11-03T00:30:00-05:00[America/Chicago]",
185
- "hour",
186
- 1,
187
- { disambiguation: "reject" },
188
- );
189
- // "" — cycled hour lands in the fall-back overlap; offset defaults to "ignore" so
190
- // disambiguation actually fires (see the C3 trap below)
191
- ```
192
-
193
- `cycleZoned` is not `addZoned`: it adjusts one field and wraps at that field's own min/max (`hour` always `0–23`, etc.) instead of carrying into the next larger field — building on `setZoned`'s J1 field-setting foundation the same way `cycleDate`/`cycleDateTime`/`cycleTime` build on `setDate`/`setDateTime`/`setTime` (see the `calculate-dates` skill). The wrap bounds themselves are plain, DST-agnostic local-field bounds; whatever DST edge case the wrapped local time lands on is then resolved by `disambiguation`/`offset`, passed straight through to `setZoned`, exactly like any other field-set call.
194
-
195
- ### Get the number of hours in a zoned calendar day
196
-
197
- ```ts
198
- getHoursInZonedDay("2024-03-10T12:00:00-04:00[America/New_York]");
199
- // 23 — spring-forward day "loses" an hour
200
-
201
- getHoursInZonedDay("2024-11-03T12:00:00-05:00[America/New_York]");
202
- // 25 — fall-back day "gains" an hour
203
-
204
- getHoursInZonedDay("2024-02-29T12:00:00+00:00[UTC]");
205
- // 24 — normal day
206
- ```
207
-
208
- Returns `23`, `24`, or `25` depending on whether the local calendar day contains a DST transition — or a fractional value for zones whose DST shift isn't a whole hour (e.g. `Australia/Lord_Howe`'s 30-minute shift returns `23.5`/`24.5`). Returns `null` for invalid input. This is zoned-only — timezone-free days are always 24 hours.
209
-
210
- ### Locale-aware week boundaries
211
-
212
- ```ts
213
- getLocaleZonedStartOfWeek("2024-02-29T12:00:00+00:00[UTC]", "en-US");
214
- // "2024-02-25T00:00:00+00:00[UTC]" (Sunday)
215
-
216
- getLocaleZonedStartOfWeek("2024-02-29T12:00:00+00:00[UTC]", "fr-FR");
217
- // "2024-02-26T00:00:00+00:00[UTC]" (Monday)
218
- ```
219
-
220
- Derives the week's first day from the locale (same as plain `getLocaleStartOfWeek`/`getLocaleEndOfWeek`). Accepts `disambiguation`/`offset` options; `offset` must stay at `"ignore"` for `disambiguation` to take effect.
221
-
222
- ### Clamp a zoned datetime to a range
223
-
224
- ```ts
225
- clampZoned(
226
- "2024-03-15T12:00:00[America/New_York]",
227
- "2024-03-01T00:00:00[America/New_York]",
228
- "2024-03-31T23:59:59[America/New_York]",
229
- );
230
- // "2024-03-15T12:00:00-04:00[America/New_York]"
231
- ```
232
-
233
- ### Find nearest zoned datetime to a target
234
-
235
- ```ts
236
- closestZonedTo(
237
- "2024-03-15T12:00:00[America/New_York]",
238
- ["2024-03-01T00:00:00[America/New_York]", "2024-03-20T00:00:00[America/New_York]"],
239
- );
240
- // "2024-03-18T00:00:00-04:00[America/New_York]"
241
- ```
242
-
243
- Returns `null` for empty candidates or invalid target.
244
-
245
- ### Read a zoned value's UTC offset
246
-
247
- ```ts
248
- getZonedOffset("2024-07-15T12:00:00-04:00[America/New_York]"); // "-04:00"
249
- getZonedOffsetAs("2024-07-15T12:00:00-04:00[America/New_York]", "minutes"); // -240
250
- getTimeZoneOffset("America/New_York", "2024-07-15T12:00:00Z"); // "-04:00"
251
- ```
252
-
253
- `getZonedOffset`/`getZonedOffsetAs` read the offset off an existing zoned value. `getTimeZoneOffset` looks one up for a bare timezone + instant, without needing a zoned value in hand.
254
-
255
- ### Format a timezone's display name
256
-
257
- ```ts
258
- formatTimeZoneName("America/New_York", "en-US", { style: "shortGeneric" }); // "ET"
259
- formatTimeZoneName("America/New_York", "en-US", { style: "long" }); // "Eastern Standard Time" or "Eastern Daylight Time", depending on today's date
260
- ```
261
-
262
- `style` covers all six `Intl.DateTimeFormatOptions` `timeZoneName` values. `"shortGeneric"`/`"longGeneric"` are season-independent (`"ET"`, `"Eastern Time"`); `"short"`/`"long"`/`"shortOffset"`/`"longOffset"` name the zone's *current* offset and flip between standard/daylight forms depending on when this is called — there's no instant parameter to pin it to.
263
-
264
- ### Check whether an instant is in daylight saving time
265
-
266
- ```ts
267
- isInDaylightSaving("2024-07-15T12:00:00-04:00[America/New_York]"); // true
268
- isInDaylightSaving("2024-01-15T12:00:00-05:00[America/New_York]"); // false
269
- ```
270
-
271
- See the Common Mistakes entry below for how this differs from `hasDaylightSaving` and `getDstTransitions`.
272
-
273
- ## Timezone Reference
274
-
275
- See [references/timezones.md](references/timezones.md) for common IANA timezone identifiers.
276
-
277
- ## Runtime ICU Data
278
-
279
- Zoned formatters delegate locale and timezone-name rendering to the host runtime's `Intl.DateTimeFormat`. Output depends on ICU data shipped with the running Node or browser. For consistent non-English output, deploy on a full-ICU Node build or polyfill `Intl`.
280
-
281
- ## Calendar-Aware Zoned Datetimes
282
-
283
- `convertZonedToCalendar(value, calendar)` expresses a zoned datetime in any of the 13 supported
284
- calendar systems, keeping the instant, wall time, UTC offset and IANA zone unchanged:
285
-
286
- ```
287
- <calendar-native-date>T<time><offset>[u-ca=<id>[;era=<era>]][<timeZone>]
288
- ```
289
-
290
- ```ts
291
- convertZonedToCalendar("2024-10-03T14:30:45-04:00[America/New_York]", "hebrew");
292
- // "5785-01-01T14:30:45-04:00[u-ca=hebrew][America/New_York]"
293
- convertZonedToCalendar("2024-10-03T14:30:45+00:00[UTC]", "japanese");
294
- // "0006-10-03T14:30:45+00:00[u-ca=japanese;era=reiwa][UTC]"
295
- ```
296
-
297
- `addZoned`/`subtractZoned` then do calendar-unit arithmetic and DST resolution in a single
298
- operation, re-deriving the calendar tag, era, wall time and offset from the result:
299
-
300
- ```ts
301
- addZoned("0031-04-30T12:00:00+09:00[u-ca=japanese;era=heisei][Asia/Tokyo]", { days: 1 });
302
- // "0001-05-01T12:00:00+09:00[u-ca=japanese;era=reiwa][Asia/Tokyo]" — era changes
303
- ```
304
-
305
- Validate with `isValidCalendarZonedDateTime` (not `isValidZonedDateTime`, which still rejects the
306
- annotation). See the Common Mistakes section for the segment-ordering trap.
307
-
308
- ## Common Mistakes
309
-
310
- ### Writing the calendar annotation in RFC 9557 order
311
-
312
- **This is the trap most likely to be hit by pattern-matching against Temporal's own docs.**
313
-
314
- GMT's calendar-annotated zoned string puts `[u-ca=...]` **before** `[timeZone]`:
315
-
316
- ```
317
- 5784-06-15T14:30:00-05:00[u-ca=hebrew][America/New_York] // correct — GMT's grammar
318
- 5784-06-15T14:30:00-05:00[America/New_York][u-ca=hebrew] // WRONG — RFC 9557 / Temporal order
319
- ```
320
-
321
- Every GMT function returns its sentinel for the second form. That looks like GMT being fussy; it
322
- is GMT refusing to guess. Temporal's ordering is a *silent misparse* here:
323
-
324
- ```ts
325
- Temporal.ZonedDateTime.from("5784-01-01T14:30:00-05:00[America/New_York][u-ca=hebrew]");
326
- // SUCCEEDS — and reads 5784 as an ISO year, not a Hebrew year. A ~3760-year error, no throw.
327
- ```
328
-
329
- GMT's digits are calendar-native (Hebrew year 5784), unlike Temporal's convention, which keeps ISO
330
- digits and only tags the calendar. The two shapes are indistinguishable by inspection, so GMT
331
- accepts exactly one ordering and rejects the other outright. The `;era=` suffix
332
- (`[u-ca=japanese;era=heisei]`) is not valid RFC 9557 at *any* ordering, so round-tripping GMT's
333
- string through `Temporal.ZonedDateTime.from` was never possible regardless.
334
-
335
- Always build these strings with `convertZonedToCalendar`, never by hand or by string concatenation.
336
-
337
- ### Converting a calendar-annotated PlainDate to a zoned value drops the calendar
338
-
339
- ```ts
340
- const hebrew = convertDateToCalendar("2024-10-03", "hebrew"); // "5785-01-01[u-ca=hebrew]"
341
- convertPlainDateTimeToZoned(`${hebrew}T14:30:00`, "America/New_York"); // "" — not a zoned grammar
342
- ```
343
-
344
- Reaching for `convertDateToCalendar` and then a zoned conversion silently produces a Gregorian
345
- value (or a sentinel), and the calendar-unit arithmetic that follows is then wrong in exactly the
346
- cases the calendar was chosen for. Use `convertZonedToCalendar` on the zoned value instead:
347
-
348
- ```ts
349
- convertZonedToCalendar("2024-10-03T14:30:45-04:00[America/New_York]", "hebrew");
350
- // "5785-01-01T14:30:45-04:00[u-ca=hebrew][America/New_York]"
351
-
352
- addZoned("5784-06-15T14:30:00-05:00[u-ca=hebrew][America/New_York]", { months: 1 });
353
- // "5784-07-15T14:30:00-04:00[u-ca=hebrew][America/New_York]"
354
- // Adar I -> Adar AND EST -> EDT in one call — no ordering of plain/ and zoned/ operations
355
- // reproduces this.
356
- ```
357
-
358
- ### Assuming every `zoned/` function accepts the annotation
359
-
360
- Only `addZoned`, `subtractZoned`, `diffZoned`, `diffZonedAsDuration`, `convertZonedToCalendar` and
361
- the `zoned/interval/*` family do. Everything else — `formatZonedDateTime`, `roundZoned`,
362
- `setZoned`, `startOfZoned`, `parseDateFromZoned`, `convertZonedToUtc`, the business-day pair, and
363
- ~60 more — still rejects it and returns its sentinel. `isValidZonedDateTime` also still returns
364
- `false` for it; validate with `isValidCalendarZonedDateTime` when you mean the calendar grammar.
365
-
366
- ### Using offset instead of IANA timezone
367
-
368
- Wrong: `"2024-03-15T14:30:45-05:00"`
369
- Correct: `"2024-03-15T14:30:45[America/New_York]"`
370
-
371
- ### Not validating timezone before use
372
-
373
- Wrong: `getZonedNow("Invalid/Zone")` — may return `""`
374
- Correct: validate with `isValidTimeZone()` first.
375
-
376
- ### Assuming `addZoned`/`subtractZoned` rejects DST gaps
377
-
378
- `disambiguation: "reject"` only catches fall-back overlaps, not spring-forward gaps. Use `convertPlainDateTimeToZoned` with `disambiguation: "reject"` if you need gap-safety.
379
-
380
- ### Passing `offset: "prefer"` with `disambiguation`
381
-
382
- `offset: "prefer"` keeps the source's offset before disambiguation is consulted, so `disambiguation` never fires. Leave `offset` at its default `"ignore"`.
383
-
384
- ### "I passed `disambiguation: 'reject'` to `setZoned` and it didn't throw"
385
-
386
- This is the C3 silent-no-op trap, and `setZoned`/`setUnix` hit it head-on because they're `.with()`-based. `offset` defaults to `"ignore"` specifically so `disambiguation` takes effect — but if you've also passed `offset: "prefer"` (or anything other than `"ignore"`), the source's still-valid offset gets kept and `disambiguation` is silently never consulted:
387
-
388
- ```ts
389
- const source = "2024-11-03T01:45:00-05:00[America/New_York]"; // second, repeated 1am of the fall-back overlap
390
-
391
- setZoned(source, { minute: 0 }, { disambiguation: "reject" });
392
- // "" — offset defaults to "ignore", so disambiguation actually fires and "reject" throws
393
-
394
- setZoned(source, { minute: 0 }, { disambiguation: "reject", offset: "prefer" });
395
- // "2024-11-03T01:00:00-05:00[America/New_York]" — offset:"prefer" keeps the source's
396
- // still-valid -05:00 offset, so disambiguation is never consulted and "reject" never fires
397
- ```
398
-
399
- Leave `offset` at its default unless you deliberately need Temporal's raw `.with()` semantics. See [The offset parameter](../../../../docs/dst-disambiguation.md#the-offset-parameter).
400
-
401
- ### Confusing `hasDaylightSaving`, `getDstTransitions`, and `isInDaylightSaving`
402
-
403
- The names are close enough to be misread. Four different DST-related questions, four different functions:
404
-
405
- | Question | Function | Scope |
406
- | --- | --- | --- |
407
- | Does this zone observe DST at all? | `hasDaylightSaving(timeZone)` | Zone-level, no instant |
408
- | Where do this zone's transitions fall? | `getDstTransitions(timeZone, year)` | Enumerates instants |
409
- | Is *this particular instant* currently in DST? | `isInDaylightSaving(value)` | A single zoned value |
410
- | What happens when construction lands on an ambiguous/nonexistent instant? | `disambiguation` / `offset` | Orthogonal — a construction-time choice, not a query |
411
-
412
- Picking the wrong one is a common mistake: `hasDaylightSaving("America/New_York")` is `true` year-round (the zone observes DST), which tells you nothing about whether a *specific* March 15th value is currently in it — that's `isInDaylightSaving`'s job.
413
-
414
- ### Reaching for `cycleZoned` when calendar arithmetic is wanted (or vice versa)
415
-
416
- `cycleZoned` is not `addZoned`. Cycling `month` by `+1` from December stays in the same year — `cycleZoned("2024-12-15T09:30:00-06:00[America/Chicago]", "month", 1)` returns `"2024-01-15T09:30:00-06:00[America/Chicago]"`, not `"2025-01-15..."`. Use `addZoned`/`subtractZoned` for calendar arithmetic where crossing a year boundary is the expected outcome; use `cycleZoned` only when a single field (e.g. a datepicker segment) must stay isolated from the others.
417
-
418
- ## References
419
-
420
- - [Common IANA timezones](references/timezones.md)
421
- - [DST Disambiguation](../../../../docs/dst-disambiguation.md)
422
- - [Temporal.ZonedDateTime](https://tc39.es/proposal-temporal/docs/zoneddatetime.html)
@@ -1,13 +0,0 @@
1
- # Common IANA Timezones
2
-
3
- | Region | Identifiers |
4
- |--------|-------------|
5
- | US | `America/New_York`, `America/Los_Angeles`, `America/Chicago`, `America/Denver` |
6
- | Canada | `America/Toronto`, `America/Vancouver`, `America/Edmonton` |
7
- | Europe | `Europe/London`, `Europe/Paris`, `Europe/Berlin`, `Europe/Moscow` |
8
- | Asia | `Asia/Tokyo`, `Asia/Shanghai`, `Asia/Singapore`, `Asia/Kolkata`, `Asia/Dubai` |
9
- | Pacific | `Pacific/Auckland`, `Pacific/Honolulu`, `Pacific/Fiji` |
10
- | Australia | `Australia/Sydney`, `Australia/Melbourne`, `Australia/Perth` |
11
- | UTC | `UTC` |
12
-
13
- For the full list, call `getTimeZones()` (~422 entries, varies by runtime/ICU) or see the [IANA timezone database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).