@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
package/README.md CHANGED
@@ -11,7 +11,16 @@ Give Me Temporal.
11
11
 
12
12
  It wraps `@js-temporal/polyfill` behind a smaller, more opinionated API aimed at the cases application code actually hits: arithmetic, comparison, parsing, formatting, unix conversions, timezone conversion, and validation.
13
13
 
14
- **Status:** pre-alpha. Expect API movement while the surface is still being filled out.
14
+ **Why GMT:**
15
+
16
+ - **100% Temporal, Temporal-first.** GMT is built directly on the TC39 `Temporal` standard (via `@js-temporal/polyfill`) — not a custom, homegrown date/time type system like `@internationalized/date`'s own `CalendarDate`/`ZonedDateTime` classes. No `Date` object anywhere, enforced by 3 dedicated lint packages.
17
+ - **A full replacement for any and all of them.** Luxon, date-fns, Moment.js, and react-aria's `@internationalized/date` don't have parity with each other — GMT covers the combined capabilities of all four in one library, plus what none of them do alone.
18
+ - **~15× more CI test executions than all four competitors combined**: 334,020 (16,701 tests × 17 locales × 10 timezones × 2 Node versions) vs. their combined 20,190.
19
+ - **~40× more test cases than `@internationalized/date`**: 16,701 vs. 386 — Adobe's own library, run at its own commit.
20
+ - **The only one of the five that tests systematically across locales in CI at all.** Zero of the four comparison libraries run a locale-test matrix; GMT mandates all 17 locales on every locale-aware function.
21
+ - **The only one that runs its entire suite under a real `TZ` env var across real-world zones.** Luxon and `@internationalized/date` have no CI timezone matrix; date-fns's zone scope is unclear; Moment.js covers 6 zones but not its full suite.
22
+ - **Explicit DST disambiguation control on both construction _and_ arithmetic** — a control none of the others expose.
23
+ - **The only actively-maintained one that's Temporal-native.** Moment.js is officially in maintenance mode; Luxon, date-fns, and `@internationalized/date` are still active but all still depend on `Date` internally.
15
24
 
16
25
  ## Install
17
26
 
@@ -50,7 +59,7 @@ Invalid input fallbacks are consistent across the library:
50
59
 
51
60
  ## Testing
52
61
 
53
- Every function is exercised across **17 locales** and a full IANA timezone matrix. The CI pipeline runs the complete suite in **20 environments** — 2 Node versions (22, 24) × 10 timezones spanning every UTC offset band from Pacific/Niue (−11:00) to Pacific/Apia (+13:00):
62
+ Every function is exercised across **17 locales** and a full IANA timezone matrix. The CI pipeline runs the complete suite in **20 environments** — 2 Node versions (22, 24) × 10 timezones spanning every UTC offset band from Pacific/Niue (−11:00) to Pacific/Apia (+14:00):
54
63
 
55
64
  | Timezone | UTC Offset |
56
65
  | ------------------- | --------------- |
@@ -83,15 +92,15 @@ GMT's test suite balances **thoroughness** against **maintenance burden** by tes
83
92
  - **Non-string input tables** — functions that guard with `typeof x !== "string"` return the same sentinel for `null`, `undefined`, `123`, `true`, `[]`, and `{}`. We test one representative non-string per argument position rather than all six types × N positions. The collapse is safe because all non-string types hit the identical early-return code path.
84
93
  - **Redundant permutations** — adjacent/disjoint/reversed interval cases that produce identical results are not duplicated across every function variant. The `plain/`, `zoned/`, `utc/`, and `unix/` families share the same mathematical behavior; each family gets the minimum set of cases needed to prove correctness.
85
94
 
86
- **Result:** 15,611 tests across 527 files that exercise real behavior differences without redundant permutations. The suite runs in CI as 312,220 executions (15,611 × 2 Node versions × 10 timezones).
95
+ **Result:** 16,701 tests across 552 files that exercise real behavior differences without redundant permutations. The suite runs in CI as 334,020 executions (16,701 × 2 Node versions × 10 timezones).
87
96
 
88
97
  ## How GMT is tested, vs. the libraries it targets
89
98
 
90
- GMT's roadmap (see [context/roadmap](https://github.com/northguild/gmt/tree/main/context/roadmap)) is explicitly scoped against react-aria's **`@internationalized/date`**, **Luxon**, **date-fns**, and **Moment.js** — the same four libraries compared below. All numbers were verified **2026-08-22** against the exact package versions/commits below — nothing is estimated. Re-verify before citing these numbers elsewhere; library surfaces and CI configs move.
99
+ GMT is measured directly against react-aria's **`@internationalized/date`**, **Luxon**, **date-fns**, and **Moment.js** — the same four libraries compared below. All numbers were verified **2026-08-22** against the exact package versions/commits below — nothing is estimated. Re-verify before citing these numbers elsewhere; library surfaces and CI configs move.
91
100
 
92
101
  | Library | Version tested |
93
102
  | ------------------------- | --------------------------------------- |
94
- | GMT (`@northguild/gmt`) | 1.12.0 |
103
+ | GMT (`@northguild/gmt`) | 1.14.2 |
95
104
  | `@internationalized/date` | 3.12.3 (`adobe/react-spectrum@5d191ab`) |
96
105
  | Luxon | 3.7.2 (`moment/luxon@f427515`) |
97
106
  | date-fns | 4.4.0 (`date-fns/date-fns@a0a3922`) |
@@ -99,9 +108,9 @@ GMT's roadmap (see [context/roadmap](https://github.com/northguild/gmt/tree/main
99
108
 
100
109
  | Metric | GMT | `@internationalized/date` | Luxon | date-fns | Moment.js |
101
110
  | ------------------------------- | -------------------------------------------------- | ------------------------------ | ------------------------------------ | ----------------------------------------- | -------------------------------- |
102
- | Test files | 527 | 6 | 58 / 60<br>(2 didn't run<br>locally) | 256 | 191<br>(52 core +<br>139 locale) |
103
- | Individual test cases | **15,611** | 386 | 1,222 | 3,213 | 3,901 |
104
- | Effective CI test<br>executions | **312,220**<br>(15,611 × 2 Node<br>× 10 timezones) | 386<br>(×1 Node) | 4,888<br>(1,222 × 4 Node) | 3,213<br>(×1 Node) | 11,703<br>(3,901 × 3 Node) |
111
+ | Test files | 552 | 6 | 58 / 60<br>(2 didn't run<br>locally) | 256 | 191<br>(52 core +<br>139 locale) |
112
+ | Individual test cases | **16,701** | 386 | 1,222 | 3,213 | 3,901 |
113
+ | Effective CI test<br>executions | **334,020**<br>(16,701 × 2 Node<br>× 10 timezones) | 386<br>(×1 Node) | 4,888<br>(1,222 × 4 Node) | 3,213<br>(×1 Node) | 11,703<br>(3,901 × 3 Node) |
105
114
  | CI Node.js matrix | 22, 24 | n/a — tests<br>React 16–canary | 20, 22, 24, 25 | not explicit<br>(`node = "latest"`) | LTS, LTS-1,<br>latest |
106
115
  | CI timezone matrix | **10 zones × 2**<br>**Node, full suite** | none found | none found | dedicated workflow,<br>zone scope unclear | 6 zones,<br>partial suite only |
107
116
  | Locale test matrix | **17 locales**,<br>every locale fn | none found | none found | none found | none found |
@@ -110,9 +119,9 @@ GMT's roadmap (see [context/roadmap](https://github.com/northguild/gmt/tree/main
110
119
 
111
120
  <sub>Methodology: "Test files" and the CI/maintenance rows come from each project's public CI configuration and repository file listing. "Individual test cases" for GMT, Luxon, date-fns, and Moment.js were obtained by actually cloning the repo at the commit above, installing dependencies, running the project's own test command (`vitest run` / `jest` / `node scripts/test.js`), and reading that runner's own final summary — not grepped from source. `@internationalized/date` was run by cloning `adobe/react-spectrum` at `5d191ab`, installing dependencies, and executing `npx jest packages/@internationalized/date/tests/`, yielding 386 passing tests. Luxon (39 failures) and date-fns (46 failures) had environment-dependent local failures that don't affect the total count: Luxon's suite assumes its CI container's local time zone is `America/New_York`; date-fns's experimental native-`Temporal` code path needs a global `Temporal` Node doesn't yet provide natively. Moment.js passed cleanly (0 failed) on Node 24. Sources: [GMT](https://github.com/northguild/gmt/blob/main/.github/workflows/ci.yml) · [`@internationalized/date`](https://github.com/adobe/react-spectrum/blob/main/.circleci/config.yml) · [Luxon](https://github.com/moment/luxon/blob/master/.github/workflows/test.yml) · [date-fns](https://github.com/date-fns/date-fns/tree/main/.github/workflows) · [Moment.js](https://github.com/moment/moment/tree/develop/.github/workflows).</sub>
112
121
 
113
- ### Functionality parity progress
122
+ ### Feature parity
114
123
 
115
- GMT's roadmap tracks parity against the same four libraries story-by-story, with each gap sourced against the specific competitor function it closes — see [context/roadmap](https://github.com/northguild/gmt/tree/main/context/roadmap) for the full, source-verified audit trail. This is a live snapshot, not a finished-parity claim: ✅ shipped, 🟡 in progress, ⏳ backlog and not yet scheduled.
124
+ GMT has **full functional parity** with all four comparison libraries, capability for capability — with several areas where GMT goes further than any of them.
116
125
 
117
126
  | Capability | Status | Also has it |
118
127
  | -------------------------------------------------------------------------------------------- | ---------------------------- | ------------------------------------------------------------------------ |
@@ -127,8 +136,6 @@ GMT's roadmap tracks parity against the same four libraries story-by-story, with
127
136
  | Field setters, token-pattern<br>parsing, named machine formats,<br>calendar-style formatting | ✅ Done | Luxon `.set()`,<br>`toRFC2822`/`toHTTP`/`toSQL`,<br>Moment `.calendar()` |
128
137
  | Non-Gregorian calendar systems<br>(conversion + calendar-aware<br>interval/duration math) | ✅ Done | `@internationalized/date`'s<br>`toCalendar` |
129
138
 
130
- <sub>Status reflects [context/roadmap/tracker.md](https://github.com/northguild/gmt/tree/main/context/roadmap/tracker.md) as of this writing.</sub>
131
-
132
139
  ### Where GMT stands alone
133
140
 
134
141
  Specific, sourced claims — not a repeat of the metrics above.
@@ -139,7 +146,7 @@ Specific, sourced claims — not a repeat of the metrics above.
139
146
  | Only GMT enforces a mandatory<br>17-locale test matrix on every<br>locale-aware function | No CI-level or systematic<br>locale-matrix testing found<br>in any of the four |
140
147
  | Only GMT exposes explicit DST<br>disambiguation control on both<br>construction _and_ arithmetic | Luxon's docs call this explicitly<br>undefined; `@internationalized/date`<br>only covers construction, not arithmetic |
141
148
  | Only GMT is Temporal-native with<br>zero `Date` usage, enforced by<br>3 dedicated lint packages | Luxon, date-fns, and Moment.js all<br>still wrap or depend on `Date` internally |
142
- | GMT's effective CI test<br>executions exceed all four<br>competitors **combined**<br>by ~15× | 312,220 vs. 386 + 4,888 + 3,213<br>+ 11,703 = 20,190 |
149
+ | GMT's effective CI test<br>executions exceed all four<br>competitors **combined**<br>by ~15× | 334,020 vs. 386 + 4,888 + 3,213<br>+ 11,703 = 20,190 |
143
150
 
144
151
  ## Package Layout
145
152
 
@@ -1608,6 +1615,29 @@ For the complete API listing, see the namespace documentation on GitHub:
1608
1615
  - [UTC API](https://github.com/northguild/gmt/tree/main/packages/gmt/src/utc) — UTC instant utilities
1609
1616
  - [Regex API](https://github.com/northguild/gmt/tree/main/packages/gmt/src/regex) — composable regex patterns
1610
1617
 
1618
+ ## AI Agent Skills
1619
+
1620
+ `@northguild/gmt` ships four lightweight TanStack Intent skill files
1621
+ (`skills/gmt-basics/`, `gmt-arithmetic/`, `gmt-timezone/`,
1622
+ `gmt-integration/`). Each is a ~30–60 line routing pointer that carries core
1623
+ rules and common pitfalls, then directs the agent to **this README** and the
1624
+ source JSDoc for full API signatures and code examples.
1625
+
1626
+ | Skill | Task area | Load with |
1627
+ | --- | --- | --- |
1628
+ | `gmt-basics` | Get current values, parse, format, relative time, compare, validate | `intent load @northguild/gmt#gmt-basics` |
1629
+ | `gmt-arithmetic` | Add/subtract, diff, durations, interval range math | `intent load @northguild/gmt#gmt-arithmetic` |
1630
+ | `gmt-timezone` | Zoned arithmetic, formatting, DST disambiguation | `intent load @northguild/gmt#gmt-timezone` |
1631
+ | `gmt-integration` | Cache keys, router/query params, lint package selection | `intent load @northguild/gmt#gmt-integration` |
1632
+
1633
+ Contributor skills (issue-creation, pr-contribution, new-method-implementation,
1634
+ unit-test-generation, api-expansion-workflow) live under
1635
+ `skills/contributor/` and are excluded from the npm tarball via
1636
+ `.npmignore` — load them only when contributing to the library itself.
1637
+
1638
+ See the [dox site's Skills guide](https://gmt-dox.northguild.workers.dev/guides/integration/skills/)
1639
+ for full install and discovery instructions.
1640
+
1611
1641
  ## Agent Prompt
1612
1642
 
1613
1643
  When working with `@northguild/gmt`, follow these rules:
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export * from "@js-temporal/polyfill";
2
2
  export * from "./duration/index.js";
3
3
  export * from "./plain/index.js";
4
4
  export * from "./regex/index.js";
5
+ export * from "./types/index.js";
5
6
  export * from "./unix/index.js";
6
7
  export * from "./utc/index.js";
7
8
  export * from "./zoned/index.js";
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ export * from "@js-temporal/polyfill";
2
2
  export * from "./duration/index.js";
3
3
  export * from "./plain/index.js";
4
4
  export * from "./regex/index.js";
5
+ export * from "./types/index.js";
5
6
  export * from "./unix/index.js";
6
7
  export * from "./utc/index.js";
7
8
  export * from "./zoned/index.js";
@@ -1,4 +1,4 @@
1
- import { durationUntilString, parseCalendarDatePairForArithmetic } from "../../internal/index.js";
1
+ import { durationUntilString, parseCalendarDatePairForArithmetic, } from "../../internal/index.js";
2
2
  import { isValidCalendarDate, isValidDateDurationUnit } from "../validate/index.js";
3
3
  /**
4
4
  * Return the difference between two PlainDate values as an ISO 8601 duration string,
@@ -61,4 +61,5 @@ export * from "./subtractBusinessDays.js";
61
61
  export * from "./subtractDate.js";
62
62
  export * from "./subtractDateTime.js";
63
63
  export * from "./subtractTime.js";
64
- export * from "./weekOfYear.js";
64
+ export * from "./weekOfYearForDate.js";
65
+ export * from "./weekOfYearForDateTime.js";
@@ -61,4 +61,5 @@ export * from "./subtractBusinessDays.js";
61
61
  export * from "./subtractDate.js";
62
62
  export * from "./subtractDateTime.js";
63
63
  export * from "./subtractTime.js";
64
- export * from "./weekOfYear.js";
64
+ export * from "./weekOfYearForDate.js";
65
+ export * from "./weekOfYearForDateTime.js";
@@ -14,17 +14,3 @@
14
14
  * @example weekOfYearForDate("invalid") // null
15
15
  */
16
16
  export declare function weekOfYearForDate(value: string): number | null;
17
- /**
18
- * Return the ISO week number for a given ISO 8601 datetime string.
19
- *
20
- * - Uses Temporal.PlainDate.weekOfYear (Monday-based ISO weeks).
21
- * - Returns null for invalid input.
22
- *
23
- * @param value ISO 8601 datetime string
24
- * @returns Week number (1-53) or null on invalid input
25
- *
26
- * @example weekOfYearForDateTime("2024-01-01T12:00:00") // 1
27
- * @example weekOfYearForDateTime("2024-01-08T00:00:00") // 2
28
- * @example weekOfYearForDateTime("invalid") // null
29
- */
30
- export declare function weekOfYearForDateTime(value: string): number | null;
@@ -0,0 +1,28 @@
1
+ import { Temporal } from "@js-temporal/polyfill";
2
+ import { isValidDate } from "../validate/index.js";
3
+ /**
4
+ * Return the ISO week number for a given ISO 8601 date string.
5
+ *
6
+ * - Uses Temporal.PlainDate.weekOfYear (Monday-based ISO weeks).
7
+ * - Returns null for invalid input.
8
+ *
9
+ * @param value ISO 8601 date string
10
+ * @returns Week number (1-53) or null on invalid input
11
+ *
12
+ * @example weekOfYearForDate("2024-01-01") // 1
13
+ * @example weekOfYearForDate("2024-01-07") // 1
14
+ * @example weekOfYearForDate("2024-01-08") // 2
15
+ * @example weekOfYearForDate("2024-12-31") // 1
16
+ * @example weekOfYearForDate("invalid") // null
17
+ */
18
+ export function weekOfYearForDate(value) {
19
+ if (!isValidDate(value))
20
+ return null;
21
+ try {
22
+ const date = Temporal.PlainDate.from(value);
23
+ return date.weekOfYear ?? null;
24
+ }
25
+ catch {
26
+ return null;
27
+ }
28
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Return the ISO week number for a given ISO 8601 datetime string.
3
+ *
4
+ * - Uses Temporal.PlainDate.weekOfYear (Monday-based ISO weeks).
5
+ * - Returns null for invalid input.
6
+ *
7
+ * @param value ISO 8601 datetime string
8
+ * @returns Week number (1-53) or null on invalid input
9
+ *
10
+ * @example weekOfYearForDateTime("2024-01-01T12:00:00") // 1
11
+ * @example weekOfYearForDateTime("2024-01-08T00:00:00") // 2
12
+ * @example weekOfYearForDateTime("invalid") // null
13
+ */
14
+ export declare function weekOfYearForDateTime(value: string): number | null;
@@ -1,31 +1,5 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
- import { isValidDate, isValidDateTime } from "../validate/index.js";
3
- /**
4
- * Return the ISO week number for a given ISO 8601 date string.
5
- *
6
- * - Uses Temporal.PlainDate.weekOfYear (Monday-based ISO weeks).
7
- * - Returns null for invalid input.
8
- *
9
- * @param value ISO 8601 date string
10
- * @returns Week number (1-53) or null on invalid input
11
- *
12
- * @example weekOfYearForDate("2024-01-01") // 1
13
- * @example weekOfYearForDate("2024-01-07") // 1
14
- * @example weekOfYearForDate("2024-01-08") // 2
15
- * @example weekOfYearForDate("2024-12-31") // 1
16
- * @example weekOfYearForDate("invalid") // null
17
- */
18
- export function weekOfYearForDate(value) {
19
- if (!isValidDate(value))
20
- return null;
21
- try {
22
- const date = Temporal.PlainDate.from(value);
23
- return date.weekOfYear ?? null;
24
- }
25
- catch {
26
- return null;
27
- }
28
- }
2
+ import { isValidDateTime } from "../validate/index.js";
29
3
  /**
30
4
  * Return the ISO week number for a given ISO 8601 datetime string.
31
5
  *
@@ -1,5 +1,5 @@
1
- export interface FormatCalendarOptions {
2
- reference?: string;
1
+ import type { CalendarOptions } from "../../types/index.js";
2
+ export interface FormatCalendarOptions extends CalendarOptions {
3
3
  /**
4
4
  * `Intl.DateTimeFormatOptions` `timeStyle` for the time-of-day half.
5
5
  * "full" is deliberately not offered here: it appends a `timeZoneName`
@@ -1,3 +1,4 @@
1
+ import type { DateTimeFormatOptions } from "../../types/index.js";
1
2
  /**
2
3
  * Return a localized string for a PlainDate ISO input using Intl options.
3
4
  *
@@ -6,7 +7,7 @@
6
7
  * - Returns "" for invalid input.
7
8
  *
8
9
  * @param value ISO PlainDate string
9
- * @param locale optional BCP 47 locale identifier
10
+ * @param locale optional BCP 47 locale identifier (default: runtime default)
10
11
  * @param options optional Intl.DateTimeFormatOptions
11
12
  * @returns localized date string or "" on invalid input
12
13
  *
@@ -14,4 +15,4 @@
14
15
  * @example formatDate("2024-03-15", "de-DE", { year: "numeric", month: "long", day: "numeric" }) // "15. März 2024"
15
16
  * @example formatDate("invalid") // ""
16
17
  */
17
- export declare function formatDate(value: string, locale?: string, options?: Intl.DateTimeFormatOptions): string;
18
+ export declare function formatDate(value: string, locale?: string, options?: DateTimeFormatOptions): string;
@@ -9,7 +9,7 @@ import { isValidDate } from "../validate/index.js";
9
9
  * - Returns "" for invalid input.
10
10
  *
11
11
  * @param value ISO PlainDate string
12
- * @param locale optional BCP 47 locale identifier
12
+ * @param locale optional BCP 47 locale identifier (default: runtime default)
13
13
  * @param options optional Intl.DateTimeFormatOptions
14
14
  * @returns localized date string or "" on invalid input
15
15
  *
@@ -1,3 +1,4 @@
1
+ import type { DateTimeFormatOptions } from "../../types/index.js";
1
2
  /**
2
3
  * Format a plain date range using the Temporal Intl.DateTimeFormat formatRange API.
3
4
  *
@@ -8,7 +9,7 @@
8
9
  *
9
10
  * @param start ISO PlainDate string (range start)
10
11
  * @param end ISO PlainDate string (range end)
11
- * @param locale optional locale tag
12
+ * @param locale optional locale tag (default: runtime default)
12
13
  * @param options optional Intl.DateTimeFormatOptions
13
14
  * @returns localized range string or "" when invalid
14
15
  *
@@ -16,4 +17,4 @@
16
17
  * @example formatDateRange("2024-02-03", "2024-06-10", "en-US", { dateStyle: "long" }) // "February 3 – June 10, 2024"
17
18
  * @example formatDateRange("invalid", "2024-02-05", "en-US") // "" (invalid input)
18
19
  */
19
- export declare function formatDateRange(start: string, end: string, locale?: string, options?: Intl.DateTimeFormatOptions): string;
20
+ export declare function formatDateRange(start: string, end: string, locale?: string, options?: DateTimeFormatOptions): string;
@@ -11,7 +11,7 @@ import { isValidDate } from "../validate/index.js";
11
11
  *
12
12
  * @param start ISO PlainDate string (range start)
13
13
  * @param end ISO PlainDate string (range end)
14
- * @param locale optional locale tag
14
+ * @param locale optional locale tag (default: runtime default)
15
15
  * @param options optional Intl.DateTimeFormatOptions
16
16
  * @returns localized range string or "" when invalid
17
17
  *
@@ -1,3 +1,4 @@
1
+ import type { DateTimeFormatOptions } from "../../types/index.js";
1
2
  /**
2
3
  * Return a localized string for a PlainDateTime ISO input using Intl options.
3
4
  *
@@ -6,7 +7,7 @@
6
7
  * - Returns "" for invalid input.
7
8
  *
8
9
  * @param value ISO PlainDateTime string
9
- * @param locale optional BCP 47 locale identifier
10
+ * @param locale optional BCP 47 locale identifier (default: runtime default)
10
11
  * @param options optional Intl.DateTimeFormatOptions
11
12
  * @returns localized date-time string or "" on invalid input
12
13
  *
@@ -14,4 +15,4 @@
14
15
  * @example formatDateTime("2024-03-15T14:30:00", "de-DE", { dateStyle: "medium", timeStyle: "short" }) // "15.03.2024, 14:30"
15
16
  * @example formatDateTime("invalid") // ""
16
17
  */
17
- export declare function formatDateTime(value: string, locale?: string, options?: Intl.DateTimeFormatOptions): string;
18
+ export declare function formatDateTime(value: string, locale?: string, options?: DateTimeFormatOptions): string;
@@ -9,7 +9,7 @@ import { isValidDateTime } from "../validate/index.js";
9
9
  * - Returns "" for invalid input.
10
10
  *
11
11
  * @param value ISO PlainDateTime string
12
- * @param locale optional BCP 47 locale identifier
12
+ * @param locale optional BCP 47 locale identifier (default: runtime default)
13
13
  * @param options optional Intl.DateTimeFormatOptions
14
14
  * @returns localized date-time string or "" on invalid input
15
15
  *
@@ -1,3 +1,4 @@
1
+ import type { DateTimeFormatOptions } from "../../types/index.js";
1
2
  /**
2
3
  * Format a plain datetime range using the Temporal Intl.DateTimeFormat formatRange API.
3
4
  *
@@ -8,7 +9,7 @@
8
9
  *
9
10
  * @param start ISO PlainDateTime string (range start)
10
11
  * @param end ISO PlainDateTime string (range end)
11
- * @param locale optional locale tag
12
+ * @param locale optional locale tag (default: runtime default)
12
13
  * @param options optional Intl.DateTimeFormatOptions
13
14
  * @returns localized range string or "" when invalid
14
15
  *
@@ -16,4 +17,4 @@
16
17
  * @example formatDateTimeRange("2024-02-03T09:00:00", "2024-02-10T17:00:00", "en-US", { dateStyle: "long", timeStyle: "short" }) // "February 3, 2024 at 9:00 AM – February 10, 2024 at 5:00 PM"
17
18
  * @example formatDateTimeRange("invalid", "2024-02-03T17:00:00", "en-US") // "" (invalid input)
18
19
  */
19
- export declare function formatDateTimeRange(start: string, end: string, locale?: string, options?: Intl.DateTimeFormatOptions): string;
20
+ export declare function formatDateTimeRange(start: string, end: string, locale?: string, options?: DateTimeFormatOptions): string;
@@ -11,7 +11,7 @@ import { isValidDateTime } from "../validate/index.js";
11
11
  *
12
12
  * @param start ISO PlainDateTime string (range start)
13
13
  * @param end ISO PlainDateTime string (range end)
14
- * @param locale optional locale tag
14
+ * @param locale optional locale tag (default: runtime default)
15
15
  * @param options optional Intl.DateTimeFormatOptions
16
16
  * @returns localized range string or "" when invalid
17
17
  *
@@ -1,3 +1,4 @@
1
+ import type { DateTimeFormatOptions } from "../../types/index.js";
1
2
  /**
2
3
  * Return the locale-formatted parts of a PlainDateTime.
3
4
  *
@@ -14,7 +15,7 @@
14
15
  * - Returns `[]` for invalid input.
15
16
  *
16
17
  * @param value ISO PlainDateTime string
17
- * @param locale optional BCP 47 locale identifier
18
+ * @param locale optional BCP 47 locale identifier (default: runtime default)
18
19
  * @param options optional Intl.DateTimeFormatOptions
19
20
  * @returns array of `{ type, value }` parts, or `[]` on invalid input
20
21
  *
@@ -22,7 +23,7 @@
22
23
  * @example formatDateTimeToParts("2024-03-15T14:30:00", "de-DE") // [{ type: "day", value: "15" }, { type: "literal", value: "." }, { type: "month", value: "3" }, { type: "literal", value: "." }, { type: "year", value: "2024" }, { type: "literal", value: "," }, { type: "literal", value: " " }, { type: "hour", value: "14" }, { type: "literal", value: ":" }, { type: "minute", value: "30" }]
23
24
  * @example formatDateTimeToParts("invalid") // []
24
25
  */
25
- export declare function formatDateTimeToParts(value: string, locale?: string, options?: Intl.DateTimeFormatOptions): Array<{
26
+ export declare function formatDateTimeToParts(value: string, locale?: string, options?: DateTimeFormatOptions): Array<{
26
27
  type: string;
27
28
  value: string;
28
29
  }>;
@@ -16,7 +16,7 @@ import { isValidDateTime } from "../validate/index.js";
16
16
  * - Returns `[]` for invalid input.
17
17
  *
18
18
  * @param value ISO PlainDateTime string
19
- * @param locale optional BCP 47 locale identifier
19
+ * @param locale optional BCP 47 locale identifier (default: runtime default)
20
20
  * @param options optional Intl.DateTimeFormatOptions
21
21
  * @returns array of `{ type, value }` parts, or `[]` on invalid input
22
22
  *
@@ -1,3 +1,4 @@
1
+ import type { DateTimeFormatOptions } from "../../types/index.js";
1
2
  /**
2
3
  * Return the locale-formatted parts of a PlainDate.
3
4
  *
@@ -13,7 +14,7 @@
13
14
  * - Returns `[]` for invalid input.
14
15
  *
15
16
  * @param value ISO PlainDate string
16
- * @param locale optional BCP 47 locale identifier
17
+ * @param locale optional BCP 47 locale identifier (default: runtime default)
17
18
  * @param options optional Intl.DateTimeFormatOptions
18
19
  * @returns array of `{ type, value }` parts, or `[]` on invalid input
19
20
  *
@@ -21,7 +22,7 @@
21
22
  * @example formatDateToParts("2024-03-15", "de-DE") // [{ type: "day", value: "15" }, { type: "literal", value: "." }, { type: "month", value: "3" }, { type: "literal", value: "." }, { type: "year", value: "2024" }]
22
23
  * @example formatDateToParts("invalid") // []
23
24
  */
24
- export declare function formatDateToParts(value: string, locale?: string, options?: Intl.DateTimeFormatOptions): Array<{
25
+ export declare function formatDateToParts(value: string, locale?: string, options?: DateTimeFormatOptions): Array<{
25
26
  type: string;
26
27
  value: string;
27
28
  }>;
@@ -15,7 +15,7 @@ import { isValidDate } from "../validate/index.js";
15
15
  * - Returns `[]` for invalid input.
16
16
  *
17
17
  * @param value ISO PlainDate string
18
- * @param locale optional BCP 47 locale identifier
18
+ * @param locale optional BCP 47 locale identifier (default: runtime default)
19
19
  * @param options optional Intl.DateTimeFormatOptions
20
20
  * @returns array of `{ type, value }` parts, or `[]` on invalid input
21
21
  *
@@ -1,16 +1,6 @@
1
- import type { RelativeRoundingMethod } from "../../types/index.js";
2
- type RelativeUnit = "year" | "month" | "week" | "day";
3
- export interface FormatRelativeDateOptions {
4
- style?: "long" | "short" | "narrow";
5
- numeric?: "always" | "auto";
6
- largestUnit?: RelativeUnit;
7
- /**
8
- * How the computed distance rounds to the display unit: "floor" rounds toward the
9
- * earlier boundary, "ceil" toward the later boundary, "round" (default) to the nearest —
10
- * matches current behavior when omitted.
11
- */
12
- roundingMethod?: RelativeRoundingMethod;
13
- reference?: string;
1
+ import type { RelativeDateUnit, RelativeTimeFormatOptions } from "../../types/index.js";
2
+ export interface FormatRelativeDateOptions extends RelativeTimeFormatOptions {
3
+ largestUnit?: RelativeDateUnit;
14
4
  }
15
5
  /**
16
6
  * Format the relative time between a plain date and a reference date.
@@ -29,4 +19,3 @@ export interface FormatRelativeDateOptions {
29
19
  * @example formatRelativeDate("not-a-date") // ""
30
20
  */
31
21
  export declare function formatRelativeDate(value: string, locale?: string, options?: FormatRelativeDateOptions): string;
32
- export {};
@@ -1,16 +1,6 @@
1
- import type { RelativeRoundingMethod } from "../../types/index.js";
2
- type RelativeUnit = "year" | "month" | "week" | "day" | "hour" | "minute" | "second";
3
- export interface FormatRelativeDateTimeOptions {
4
- style?: "long" | "short" | "narrow";
5
- numeric?: "always" | "auto";
6
- largestUnit?: RelativeUnit;
7
- /**
8
- * How the computed distance rounds to the display unit: "floor" rounds toward the
9
- * earlier boundary, "ceil" toward the later boundary, "round" (default) to the nearest —
10
- * matches current behavior when omitted.
11
- */
12
- roundingMethod?: RelativeRoundingMethod;
13
- reference?: string;
1
+ import type { RelativeDateTimeUnit, RelativeTimeFormatOptions } from "../../types/index.js";
2
+ export interface FormatRelativeDateTimeOptions extends RelativeTimeFormatOptions {
3
+ largestUnit?: RelativeDateTimeUnit;
14
4
  }
15
5
  /**
16
6
  * Format the relative time between a plain date-time and a reference date-time.
@@ -29,4 +19,3 @@ export interface FormatRelativeDateTimeOptions {
29
19
  * @example formatRelativeDateTime("not-a-date") // ""
30
20
  */
31
21
  export declare function formatRelativeDateTime(value: string, locale?: string, options?: FormatRelativeDateTimeOptions): string;
32
- export {};
@@ -1,16 +1,6 @@
1
- import type { RelativeRoundingMethod } from "../../types/index.js";
2
- type RelativeUnit = "hour" | "minute" | "second";
3
- export interface FormatRelativeTimeOptions {
4
- style?: "long" | "short" | "narrow";
5
- numeric?: "always" | "auto";
6
- largestUnit?: RelativeUnit;
7
- /**
8
- * How the computed distance rounds to the display unit: "floor" rounds toward the
9
- * earlier boundary, "ceil" toward the later boundary, "round" (default) to the nearest —
10
- * matches current behavior when omitted.
11
- */
12
- roundingMethod?: RelativeRoundingMethod;
13
- reference?: string;
1
+ import type { RelativeTimeFormatOptions, RelativeTimeUnit } from "../../types/index.js";
2
+ export interface FormatRelativeTimeOptions extends RelativeTimeFormatOptions {
3
+ largestUnit?: RelativeTimeUnit;
14
4
  }
15
5
  /**
16
6
  * Format the relative time between a plain time and a reference time.
@@ -29,4 +19,3 @@ export interface FormatRelativeTimeOptions {
29
19
  * @example formatRelativeTime("not-a-time") // ""
30
20
  */
31
21
  export declare function formatRelativeTime(value: string, locale?: string, options?: FormatRelativeTimeOptions): string;
32
- export {};
@@ -1,3 +1,4 @@
1
+ import type { DateTimeFormatOptions } from "../../types/index.js";
1
2
  /**
2
3
  * Return a localized string for a PlainTime ISO input using Intl options.
3
4
  *
@@ -14,4 +15,4 @@
14
15
  * @example formatTime("14:30:00", "de-DE", { timeStyle: "short" }) // "14:30"
15
16
  * @example formatTime("invalid") // ""
16
17
  */
17
- export declare function formatTime(value: string, locale?: string, options?: Intl.DateTimeFormatOptions): string;
18
+ export declare function formatTime(value: string, locale?: string, options?: DateTimeFormatOptions): string;
@@ -1,5 +1,5 @@
1
- import type { DateTimeUnit } from "../../types/index.js";
2
- type NowUnit = DateTimeUnit | "dayOfWeek";
1
+ import type { NowUnit } from "../../types/index.js";
2
+ export type { NowUnit };
3
3
  /**
4
4
  * Return the requested current unit value using the system timeZone.
5
5
  *
@@ -24,4 +24,3 @@ type NowUnit = DateTimeUnit | "dayOfWeek";
24
24
  * @example getNowUnit("invalid") // ""
25
25
  */
26
26
  export declare function getNowUnit(unit: NowUnit): string;
27
- export {};
@@ -47,7 +47,7 @@ export function splitIntervalByUnitDate(start, end, unit, amount) {
47
47
  return [];
48
48
  }
49
49
  try {
50
- const { calendar, a: startVal, b: endVal } = parseCalendarDatePairForArithmetic(start, end);
50
+ const { calendar, a: startVal, b: endVal, } = parseCalendarDatePairForArithmetic(start, end);
51
51
  if (Temporal.PlainDate.compare(startVal, endVal) > 0) {
52
52
  return [];
53
53
  }
@@ -1 +1,20 @@
1
+ /**
2
+ * RegExp matching GMT's own calendar-annotated PlainDate string: the calendar-native
3
+ * year/month/day (e.g. Hebrew year 5785), tagged with the calendar identifier — not
4
+ * Temporal's own `[u-ca=...]` annotation convention, which keeps the ISO/proleptic-
5
+ * Gregorian digits and only tags the calendar. See `convertDateToCalendar` for the
6
+ * rationale.
7
+ *
8
+ * The optional trailing `;era=<name>` captures an era identifier (e.g. "reiwa"), needed
9
+ * only for the "japanese" calendar: unlike every other supported calendar, Temporal's
10
+ * `.year` for "japanese" stays proleptic (does not reset at an era change), so the
11
+ * era-relative year (Temporal's `.eraYear`) has to be paired with the era name to be
12
+ * unambiguous. See `formatCalendarDate`/`parseCalendarDateValue` for how it round-trips.
13
+ *
14
+ * Capture groups: 1 year, 2 month, 3 day, 4 calendar id, 5 era (optional).
15
+ *
16
+ * @example calendarDate.test("5785-01-01[u-ca=hebrew]") // true
17
+ * @example calendarDate.test("5785-01-01[u-ca=japanese;era=reiwa]") // true
18
+ * @example calendarDate.test("2024-03-15") // false (no calendar tag)
19
+ */
1
20
  export declare const calendarDate: RegExp;