temporal-fmt 0.9.2 → 0.9.4

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 (103) hide show
  1. package/README.md +480 -9
  2. package/dist/calendarUtils.cjs +259 -4
  3. package/dist/calendarUtils.cjs.map +1 -1
  4. package/dist/calendarUtils.js +33 -1
  5. package/dist/chunk-4N3WCGEY.js +183 -0
  6. package/dist/{chunk-4JWGUR4O.js.map → chunk-4N3WCGEY.js.map} +1 -1
  7. package/dist/chunk-5UTV5VP6.js +984 -0
  8. package/dist/chunk-5UTV5VP6.js.map +1 -0
  9. package/dist/chunk-ACKKWH5Z.js +578 -0
  10. package/dist/{chunk-2JHEV7ZF.js.map → chunk-ACKKWH5Z.js.map} +1 -1
  11. package/dist/chunk-EGUUO6LE.js +439 -0
  12. package/dist/chunk-EGUUO6LE.js.map +1 -0
  13. package/dist/chunk-FBPHNRVW.js +2939 -0
  14. package/dist/chunk-FBPHNRVW.js.map +1 -0
  15. package/dist/chunk-GPB4JHGI.js +65 -0
  16. package/dist/chunk-GPB4JHGI.js.map +1 -0
  17. package/dist/chunk-H7YQX25T.js +170 -0
  18. package/dist/{chunk-J2AQNXF2.js.map → chunk-H7YQX25T.js.map} +1 -1
  19. package/dist/chunk-HXY2GUUM.js +182 -0
  20. package/dist/{chunk-EHLRZULM.js.map → chunk-HXY2GUUM.js.map} +1 -1
  21. package/dist/chunk-L24NPTAJ.js +328 -0
  22. package/dist/chunk-L24NPTAJ.js.map +1 -0
  23. package/dist/chunk-M3GDTHMT.js +169 -0
  24. package/dist/chunk-M3GDTHMT.js.map +1 -0
  25. package/dist/chunk-MKPDLQKD.js +51 -0
  26. package/dist/chunk-MKPDLQKD.js.map +1 -0
  27. package/dist/chunk-TSLPIURC.js +242 -0
  28. package/dist/{chunk-VQXUMFB2.js.map → chunk-TSLPIURC.js.map} +1 -1
  29. package/dist/chunk-UOPAV3WX.js +75 -0
  30. package/dist/chunk-UOPAV3WX.js.map +1 -0
  31. package/dist/chunk-VNIUIQA4.js +398 -0
  32. package/dist/chunk-VNIUIQA4.js.map +1 -0
  33. package/dist/chunk-YEUASGDK.js +9 -0
  34. package/dist/chunk-YEUASGDK.js.map +1 -0
  35. package/dist/chunk-ZQZF5EXW.js +29 -0
  36. package/dist/chunk-ZQZF5EXW.js.map +1 -0
  37. package/dist/config.d.cts +4 -2
  38. package/dist/config.d.ts +4 -2
  39. package/dist/duration.cjs +638 -26
  40. package/dist/duration.cjs.map +1 -1
  41. package/dist/duration.js +28 -1
  42. package/dist/format.cjs +833 -35
  43. package/dist/format.cjs.map +1 -1
  44. package/dist/format.js +20 -1
  45. package/dist/index.cjs +7698 -163
  46. package/dist/index.cjs.map +1 -1
  47. package/dist/index.d.cts +108 -24
  48. package/dist/index.d.ts +108 -24
  49. package/dist/index.js +1536 -58
  50. package/dist/index.js.map +1 -1
  51. package/dist/interval.cjs +5480 -35
  52. package/dist/interval.cjs.map +1 -1
  53. package/dist/interval.js +46 -1
  54. package/dist/localeRegistry.cjs +375 -32
  55. package/dist/localeRegistry.cjs.map +1 -1
  56. package/dist/localeRegistry.js +11 -1
  57. package/dist/modApi.d.cts +131 -0
  58. package/dist/modApi.d.ts +131 -0
  59. package/dist/parse.cjs +1797 -70
  60. package/dist/parse.cjs.map +1 -1
  61. package/dist/parse.js +20 -1
  62. package/dist/pattern.d.cts +1 -0
  63. package/dist/pattern.d.ts +1 -0
  64. package/dist/recurrence.cjs +452 -20
  65. package/dist/recurrence.cjs.map +1 -1
  66. package/dist/recurrence.js +19 -1
  67. package/dist/relativeTime.cjs +268 -21
  68. package/dist/relativeTime.cjs.map +1 -1
  69. package/dist/relativeTime.js +14 -1
  70. package/dist/runtime.d.cts +201 -0
  71. package/dist/runtime.d.ts +201 -0
  72. package/dist/timezone.cjs +387 -20
  73. package/dist/timezone.cjs.map +1 -1
  74. package/dist/timezone.js +26 -1
  75. package/package.json +4 -6
  76. package/scripts/cli.mjs +27 -5
  77. package/dist/chunk-2JHEV7ZF.js +0 -7
  78. package/dist/chunk-3MZLTVP3.js +0 -2
  79. package/dist/chunk-3MZLTVP3.js.map +0 -1
  80. package/dist/chunk-4JWGUR4O.js +0 -11
  81. package/dist/chunk-5U5WJ465.js +0 -36
  82. package/dist/chunk-5U5WJ465.js.map +0 -1
  83. package/dist/chunk-C5YESWFT.js +0 -2
  84. package/dist/chunk-C5YESWFT.js.map +0 -1
  85. package/dist/chunk-C6ZZ62ET.js +0 -2
  86. package/dist/chunk-C6ZZ62ET.js.map +0 -1
  87. package/dist/chunk-EHLRZULM.js +0 -5
  88. package/dist/chunk-F4RGUDA3.js +0 -2
  89. package/dist/chunk-F4RGUDA3.js.map +0 -1
  90. package/dist/chunk-J2AQNXF2.js +0 -2
  91. package/dist/chunk-NBXF7V5B.js +0 -2
  92. package/dist/chunk-NBXF7V5B.js.map +0 -1
  93. package/dist/chunk-R52YOKI3.js +0 -7
  94. package/dist/chunk-R52YOKI3.js.map +0 -1
  95. package/dist/chunk-UJR6DHXY.js +0 -2
  96. package/dist/chunk-UJR6DHXY.js.map +0 -1
  97. package/dist/chunk-VQXUMFB2.js +0 -21
  98. package/dist/chunk-XH46JNPK.js +0 -2
  99. package/dist/chunk-XH46JNPK.js.map +0 -1
  100. package/dist/chunk-YB6YAG7E.js +0 -35
  101. package/dist/chunk-YB6YAG7E.js.map +0 -1
  102. package/dist/chunk-ZGMTY52O.js +0 -2
  103. package/dist/chunk-ZGMTY52O.js.map +0 -1
@@ -0,0 +1,51 @@
1
+ // src/isoWeek.ts
2
+ var CUMULATIVE_DAYS_BY_MONTH = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
3
+ function isGregorianLeapYear(year) {
4
+ return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
5
+ }
6
+ function daysInYear(year) {
7
+ return isGregorianLeapYear(year) ? 366 : 365;
8
+ }
9
+ function dayOfYear(year, month, day) {
10
+ let doy = CUMULATIVE_DAYS_BY_MONTH[month - 1] + day;
11
+ if (month > 2 && isGregorianLeapYear(year)) doy += 1;
12
+ return doy;
13
+ }
14
+ var REFERENCE_YEAR = 2e3;
15
+ function dayOfWeekOfJan1(year) {
16
+ let offset = 0;
17
+ if (year >= REFERENCE_YEAR) {
18
+ for (let y = REFERENCE_YEAR; y < year; y++) offset += daysInYear(y);
19
+ } else {
20
+ for (let y = year; y < REFERENCE_YEAR; y++) offset -= daysInYear(y);
21
+ }
22
+ const zeroIndexed = ((6 - 1 + offset) % 7 + 7) % 7;
23
+ return zeroIndexed + 1;
24
+ }
25
+ function isoWeekYearAndWeek(year, month, day, dayOfWeek) {
26
+ const doy = dayOfYear(year, month, day);
27
+ const thursdayDoyRelative = doy + (4 - dayOfWeek);
28
+ let isoYear;
29
+ let thursdayDoy;
30
+ if (thursdayDoyRelative < 1) {
31
+ isoYear = year - 1;
32
+ thursdayDoy = thursdayDoyRelative + daysInYear(isoYear);
33
+ } else if (thursdayDoyRelative > daysInYear(year)) {
34
+ isoYear = year + 1;
35
+ thursdayDoy = thursdayDoyRelative - daysInYear(year);
36
+ } else {
37
+ isoYear = year;
38
+ thursdayDoy = thursdayDoyRelative;
39
+ }
40
+ const jan1Dow = dayOfWeekOfJan1(isoYear);
41
+ const firstThursdayDoy = 1 + (4 - jan1Dow + 7) % 7;
42
+ const week = 1 + Math.floor((thursdayDoy - firstThursdayDoy) / 7);
43
+ return { isoYear, week };
44
+ }
45
+
46
+ export {
47
+ isGregorianLeapYear,
48
+ dayOfYear,
49
+ isoWeekYearAndWeek
50
+ };
51
+ //# sourceMappingURL=chunk-MKPDLQKD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/isoWeek.ts"],"sourcesContent":["// ISO week stuff. week runs Mon-Sun, and week 1 is whichever week has\n// the year's first Thursday in it (same as saying \"the week with Jan 4\").\n// took me a minute to wrap my head around this but the upshot is late-Dec\n// dates can land in week 1 of NEXT year, and early-Jan dates can land in\n// week 52/53 of the PREVIOUS year. that adjacent year is what RRRR prints,\n// not the plain calendar year.\n//\n// doing this with plain year/month/day + dayOfWeek math instead of asking\n// Temporal for it, since format() only has whatever fields got handed in\n// and dragging in a whole Temporal implementation just for week numbers\n// felt like overkill (also breaks for people not on setTemporal()).\n\nconst DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\nconst CUMULATIVE_DAYS_BY_MONTH = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];\n\nexport function isGregorianLeapYear(year: number): boolean {\n // divisible by 4, unless it's a century, then it also needs /400.\n // Temporal's iso8601 calendar never switches to Julian, so this rule\n // just applies all the way back, even for BCE years.\n return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n}\n\nfunction daysInYear(year: number): 365 | 366 {\n return isGregorianLeapYear(year) ? 366 : 365;\n}\n\nexport function dayOfYear(year: number, month: number, day: number): number {\n let doy = CUMULATIVE_DAYS_BY_MONTH[month - 1]! + day;\n if (month > 2 && isGregorianLeapYear(year)) doy += 1;\n return doy;\n}\n\n// Jan 1 2000 was a Saturday (ISO dow 6). picked this as an anchor point\n// since it's easier than reaching for Zeller's congruence every time,\n// and obviously this fact about Jan 1 2000 isn't going to change on us\nconst REFERENCE_YEAR = 2000;\nconst REFERENCE_JAN1_DAY_OF_WEEK = 6;\n\nfunction dayOfWeekOfJan1(year: number): number {\n // walk year by year from 2000 instead of doing this from scratch every\n // time — most callers pass a current-era year so this loop is short anyway\n let offset = 0;\n if (year >= REFERENCE_YEAR) {\n for (let y = REFERENCE_YEAR; y < year; y++) offset += daysInYear(y);\n } else {\n for (let y = year; y < REFERENCE_YEAR; y++) offset -= daysInYear(y);\n }\n // now turn \"days since Jan 1 2000\" into an ISO weekday. Jan 1 2000 was a 6\n // (Sat), so: zero-indexed = (6-1 + offset) mod 7, then bump back to 1-indexed\n const zeroIndexed = (((6 - 1 + offset) % 7) + 7) % 7;\n return zeroIndexed + 1;\n}\n\nexport interface IsoWeekDate {\n isoYear: number;\n week: number; // goes 1 to 53\n}\n\nexport function isoWeekYearAndWeek(year: number, month: number, day: number, dayOfWeek: number): IsoWeekDate {\n // step 1: figure out the Thursday of this week — whatever calendar year\n // that Thursday's in IS the ISO week-numbering year. doing this with\n // day-of-year offsets so we don't need an actual Temporal.PlainDate here\n const doy = dayOfYear(year, month, day);\n const thursdayDoyRelative = doy + (4 - dayOfWeek); // can go negative or past daysInYear, that's fine\n\n let isoYear: number;\n let thursdayDoy: number;\n if (thursdayDoyRelative < 1) {\n isoYear = year - 1;\n thursdayDoy = thursdayDoyRelative + daysInYear(isoYear);\n } else if (thursdayDoyRelative > daysInYear(year)) {\n isoYear = year + 1;\n thursdayDoy = thursdayDoyRelative - daysInYear(year);\n } else {\n isoYear = year;\n thursdayDoy = thursdayDoyRelative;\n }\n\n // step 2: find the first Thursday of isoYear, that one's week 1 by definition.\n // depends entirely on which weekday Jan 1 lands on\n const jan1Dow = dayOfWeekOfJan1(isoYear);\n const firstThursdayDoy = 1 + ((4 - jan1Dow + 7) % 7); // always lands somewhere 1-7\n\n // step 3: just count how many full weeks between the two Thursdays\n const week = 1 + Math.floor((thursdayDoy - firstThursdayDoy) / 7);\n return { isoYear, week };\n}\n"],"mappings":";AAaA,IAAM,2BAA2B,CAAC,GAAG,IAAI,IAAI,IAAI,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAEhF,SAAS,oBAAoB,MAAuB;AAIzD,SAAQ,OAAO,MAAM,KAAK,OAAO,QAAQ,KAAM,OAAO,QAAQ;AAChE;AAEA,SAAS,WAAW,MAAyB;AAC3C,SAAO,oBAAoB,IAAI,IAAI,MAAM;AAC3C;AAEO,SAAS,UAAU,MAAc,OAAe,KAAqB;AAC1E,MAAI,MAAM,yBAAyB,QAAQ,CAAC,IAAK;AACjD,MAAI,QAAQ,KAAK,oBAAoB,IAAI,EAAG,QAAO;AACnD,SAAO;AACT;AAKA,IAAM,iBAAiB;AAGvB,SAAS,gBAAgB,MAAsB;AAG7C,MAAI,SAAS;AACb,MAAI,QAAQ,gBAAgB;AAC1B,aAAS,IAAI,gBAAgB,IAAI,MAAM,IAAK,WAAU,WAAW,CAAC;AAAA,EACpE,OAAO;AACL,aAAS,IAAI,MAAM,IAAI,gBAAgB,IAAK,WAAU,WAAW,CAAC;AAAA,EACpE;AAGA,QAAM,gBAAiB,IAAI,IAAI,UAAU,IAAK,KAAK;AACnD,SAAO,cAAc;AACvB;AAOO,SAAS,mBAAmB,MAAc,OAAe,KAAa,WAAgC;AAI3G,QAAM,MAAM,UAAU,MAAM,OAAO,GAAG;AACtC,QAAM,sBAAsB,OAAO,IAAI;AAEvC,MAAI;AACJ,MAAI;AACJ,MAAI,sBAAsB,GAAG;AAC3B,cAAU,OAAO;AACjB,kBAAc,sBAAsB,WAAW,OAAO;AAAA,EACxD,WAAW,sBAAsB,WAAW,IAAI,GAAG;AACjD,cAAU,OAAO;AACjB,kBAAc,sBAAsB,WAAW,IAAI;AAAA,EACrD,OAAO;AACL,cAAU;AACV,kBAAc;AAAA,EAChB;AAIA,QAAM,UAAU,gBAAgB,OAAO;AACvC,QAAM,mBAAmB,KAAM,IAAI,UAAU,KAAK;AAGlD,QAAM,OAAO,IAAI,KAAK,OAAO,cAAc,oBAAoB,CAAC;AAChE,SAAO,EAAE,SAAS,KAAK;AACzB;","names":[]}
@@ -0,0 +1,242 @@
1
+ import {
2
+ asDateFieldView,
3
+ daysInMonth
4
+ } from "./chunk-HXY2GUUM.js";
5
+
6
+ // src/arithmetic.ts
7
+ function asDateTime(value) {
8
+ return asDateFieldView(value);
9
+ }
10
+ function recomputeDayOfWeek(view) {
11
+ if (typeof view.dayOfWeek !== "number") return;
12
+ /* c8 ignore start @preserve -- unreachable: every call site (add()'s
13
+ 'years'/'months' cases, shiftDays()) passes a `result` whose
14
+ year/month/day were just explicitly set, and the value originally
15
+ came from asDateTime()/asDateFieldView(), which throws unless
16
+ year/month/day are all present as numbers. So by the time this guard
17
+ runs, all three are guaranteed valid. Kept in case a future caller
18
+ constructs a DateTimeFieldView bypassing that validation. */
19
+ if (typeof view.year !== "number" || typeof view.month !== "number" || typeof view.day !== "number") return;
20
+ /* c8 ignore stop @preserve */
21
+ const jsDow = new Date(Date.UTC(view.year, view.month - 1, view.day)).getUTCDay();
22
+ view.dayOfWeek = jsDow === 0 ? 7 : jsDow;
23
+ }
24
+ function add(value, amount, unit) {
25
+ const v = asDateTime(value);
26
+ let result = { ...v };
27
+ switch (unit) {
28
+ case "years": {
29
+ /* c8 ignore start @preserve -- the `?? 0` fallback is unreachable:
30
+ asDateTime()/asDateFieldView() (called at the top of add()) throws
31
+ unless year is present as a number, so result.year is never
32
+ undefined here. Kept as a guard against a future change that
33
+ relaxes that validation. */
34
+ result.year = (result.year ?? 0) + amount;
35
+ /* c8 ignore stop @preserve */
36
+ const maxDay = daysInMonth({ year: result.year, month: result.month });
37
+ if (result.day > maxDay) result.day = maxDay;
38
+ recomputeDayOfWeek(result);
39
+ break;
40
+ }
41
+ case "months": {
42
+ /* c8 ignore start @preserve -- both `??` fallbacks are unreachable
43
+ for the same reason as the 'years' case above: asDateFieldView()
44
+ guarantees year and month are present numbers before add() ever
45
+ reaches here. */
46
+ const total = (result.year ?? 0) * 12 + (result.month ?? 1) - 1 + amount;
47
+ /* c8 ignore stop @preserve */
48
+ result.year = Math.floor(total / 12);
49
+ result.month = total % 12 + 1;
50
+ if (result.month < 1) {
51
+ result.month += 12;
52
+ result.year -= 1;
53
+ }
54
+ /* c8 ignore start @preserve -- unreachable: (total % 12) + 1 can never
55
+ exceed 12 for any integer total in JS (its range is [-10, 12] since
56
+ JS's % can return a negative remainder but never one with
57
+ magnitude >= 12, so adding 1 tops out at 12). Only the < 1 branch
58
+ above is reachable; this was written symmetrically with it but the
59
+ overflow direction it guards against can't occur. Kept rather than
60
+ removed since it costs nothing and documents the intent. */
61
+ if (result.month > 12) {
62
+ result.month -= 12;
63
+ result.year += 1;
64
+ }
65
+ /* c8 ignore stop @preserve */
66
+ const maxDay = daysInMonth({ year: result.year, month: result.month });
67
+ if (result.day > maxDay) result.day = maxDay;
68
+ recomputeDayOfWeek(result);
69
+ break;
70
+ }
71
+ case "weeks":
72
+ result = shiftDays(result, amount * 7);
73
+ break;
74
+ case "days":
75
+ result = shiftDays(result, amount);
76
+ break;
77
+ case "hours":
78
+ result = shiftTime(result, amount * 36e5);
79
+ break;
80
+ case "minutes":
81
+ result = shiftTime(result, amount * 6e4);
82
+ break;
83
+ case "seconds":
84
+ result = shiftTime(result, amount * 1e3);
85
+ break;
86
+ case "milliseconds":
87
+ result = shiftTime(result, amount);
88
+ break;
89
+ }
90
+ return result;
91
+ }
92
+ function shiftDays(v, days) {
93
+ const y = v.year, m = v.month, d = v.day;
94
+ const y2 = m <= 2 ? y - 1 : y;
95
+ const era = Math.floor((y2 >= 0 ? y2 : y2 - 399) / 400);
96
+ const yoe = y2 - era * 400;
97
+ const m2 = m > 2 ? m - 3 : m + 9;
98
+ const doy = Math.floor((153 * m2 + 2) / 5) + d - 1;
99
+ const doe = yoe * 365 + Math.floor(yoe / 4) - Math.floor(yoe / 100) + doy;
100
+ const totalDays = era * 146097 + doe - 719468 + days;
101
+ const z = totalDays + 719468;
102
+ const era2 = Math.floor((z >= 0 ? z : z - 146096) / 146097);
103
+ const doe2 = z - era2 * 146097;
104
+ const yoe2 = Math.floor((doe2 - Math.floor(doe2 / 1460) + Math.floor(doe2 / 36524) - Math.floor(doe2 / 146096)) / 365);
105
+ const y2out = yoe2 + era2 * 400;
106
+ const doy2 = doe2 - (365 * yoe2 + Math.floor(yoe2 / 4) - Math.floor(yoe2 / 100));
107
+ const mp = Math.floor((5 * doy2 + 2) / 153);
108
+ const d2 = doy2 - Math.floor((153 * mp + 2) / 5) + 1;
109
+ const m2out = mp < 10 ? mp + 3 : mp - 9;
110
+ const yOut = m2out <= 2 ? y2out + 1 : y2out;
111
+ const result = { ...v, year: yOut, month: m2out, day: d2 };
112
+ recomputeDayOfWeek(result);
113
+ return result;
114
+ }
115
+ function shiftTime(v, msDelta) {
116
+ const MS_PER_DAY = 864e5;
117
+ const MS_PER_HOUR = 36e5;
118
+ const MS_PER_MINUTE = 6e4;
119
+ const MS_PER_SECOND = 1e3;
120
+ const totalMs = (v.hour ?? 0) * MS_PER_HOUR + (v.minute ?? 0) * MS_PER_MINUTE + (v.second ?? 0) * MS_PER_SECOND + (v.millisecond ?? 0) + msDelta;
121
+ const dayOverflow = Math.floor(totalMs / MS_PER_DAY);
122
+ let withinDay = totalMs % MS_PER_DAY;
123
+ if (withinDay < 0) {
124
+ withinDay += MS_PER_DAY;
125
+ }
126
+ const hour = Math.floor(withinDay / MS_PER_HOUR);
127
+ const minute = Math.floor(withinDay % MS_PER_HOUR / MS_PER_MINUTE);
128
+ const second = Math.floor(withinDay % MS_PER_MINUTE / MS_PER_SECOND);
129
+ const millisecond = withinDay % MS_PER_SECOND;
130
+ const result = { ...v, hour, minute, second, millisecond };
131
+ if (dayOverflow !== 0) {
132
+ return shiftDays(result, dayOverflow);
133
+ }
134
+ return result;
135
+ }
136
+ function subtract(value, amount, unit) {
137
+ return add(value, -amount, unit);
138
+ }
139
+ var addYears = (v, n) => add(v, n, "years");
140
+ var addMonths = (v, n) => add(v, n, "months");
141
+ var addWeeks = (v, n) => add(v, n, "weeks");
142
+ var addDays = (v, n) => add(v, n, "days");
143
+ var addHours = (v, n) => add(v, n, "hours");
144
+ var addMinutes = (v, n) => add(v, n, "minutes");
145
+ var addSeconds = (v, n) => add(v, n, "seconds");
146
+ var addMilliseconds = (v, n) => add(v, n, "milliseconds");
147
+ var subtractYears = (v, n) => subtract(v, n, "years");
148
+ var subtractMonths = (v, n) => subtract(v, n, "months");
149
+ var subtractWeeks = (v, n) => subtract(v, n, "weeks");
150
+ var subtractDays = (v, n) => subtract(v, n, "days");
151
+ var subtractHours = (v, n) => subtract(v, n, "hours");
152
+ var subtractMinutes = (v, n) => subtract(v, n, "minutes");
153
+ var subtractSeconds = (v, n) => subtract(v, n, "seconds");
154
+ var subtractMilliseconds = (v, n) => subtract(v, n, "milliseconds");
155
+ function difference(a, b, unit) {
156
+ const av = asDateTime(a);
157
+ const bv = asDateTime(b);
158
+ if (unit === "years") {
159
+ return bv.year - av.year;
160
+ }
161
+ if (unit === "months") {
162
+ return bv.year * 12 + bv.month - 1 - (av.year * 12 + av.month - 1);
163
+ }
164
+ if (unit === "weeks" || unit === "days") {
165
+ const aDays = toDayCount(av);
166
+ const bDays = toDayCount(bv);
167
+ const days = bDays - aDays;
168
+ return unit === "weeks" ? Math.trunc(days / 7) : days;
169
+ }
170
+ const MS_PER_HOUR = 36e5;
171
+ const MS_PER_MINUTE = 6e4;
172
+ const MS_PER_SECOND = 1e3;
173
+ const aMs = toTotalMs(av);
174
+ const bMs = toTotalMs(bv);
175
+ const diffMs = bMs - aMs;
176
+ switch (unit) {
177
+ case "hours":
178
+ return Math.trunc(diffMs / MS_PER_HOUR);
179
+ case "minutes":
180
+ return Math.trunc(diffMs / MS_PER_MINUTE);
181
+ case "seconds":
182
+ return Math.trunc(diffMs / MS_PER_SECOND);
183
+ case "milliseconds":
184
+ return diffMs;
185
+ }
186
+ }
187
+ function toDayCount(v) {
188
+ const y = v.year, m = v.month, d = v.day;
189
+ const y2 = m <= 2 ? y - 1 : y;
190
+ const era = Math.floor((y2 >= 0 ? y2 : y2 - 399) / 400);
191
+ const yoe = y2 - era * 400;
192
+ const m2 = m > 2 ? m - 3 : m + 9;
193
+ const doy = Math.floor((153 * m2 + 2) / 5) + d - 1;
194
+ const doe = yoe * 365 + Math.floor(yoe / 4) - Math.floor(yoe / 100) + doy;
195
+ return era * 146097 + doe - 719468;
196
+ }
197
+ function toTotalMs(v) {
198
+ const MS_PER_DAY = 864e5;
199
+ const MS_PER_HOUR = 36e5;
200
+ const MS_PER_MINUTE = 6e4;
201
+ const MS_PER_SECOND = 1e3;
202
+ return toDayCount(v) * MS_PER_DAY + (v.hour ?? 0) * MS_PER_HOUR + (v.minute ?? 0) * MS_PER_MINUTE + (v.second ?? 0) * MS_PER_SECOND + (v.millisecond ?? 0);
203
+ }
204
+ var differenceInYears = (a, b) => difference(a, b, "years");
205
+ var differenceInMonths = (a, b) => difference(a, b, "months");
206
+ var differenceInWeeks = (a, b) => difference(a, b, "weeks");
207
+ var differenceInDays = (a, b) => difference(a, b, "days");
208
+ var differenceInHours = (a, b) => difference(a, b, "hours");
209
+ var differenceInMinutes = (a, b) => difference(a, b, "minutes");
210
+ var differenceInSeconds = (a, b) => difference(a, b, "seconds");
211
+ var differenceInMilliseconds = (a, b) => difference(a, b, "milliseconds");
212
+
213
+ export {
214
+ add,
215
+ subtract,
216
+ addYears,
217
+ addMonths,
218
+ addWeeks,
219
+ addDays,
220
+ addHours,
221
+ addMinutes,
222
+ addSeconds,
223
+ addMilliseconds,
224
+ subtractYears,
225
+ subtractMonths,
226
+ subtractWeeks,
227
+ subtractDays,
228
+ subtractHours,
229
+ subtractMinutes,
230
+ subtractSeconds,
231
+ subtractMilliseconds,
232
+ difference,
233
+ differenceInYears,
234
+ differenceInMonths,
235
+ differenceInWeeks,
236
+ differenceInDays,
237
+ differenceInHours,
238
+ differenceInMinutes,
239
+ differenceInSeconds,
240
+ differenceInMilliseconds
241
+ };
242
+ //# sourceMappingURL=chunk-TSLPIURC.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/arithmetic.ts"],"sourcesContent":["// Date arithmetic helpers. Pure functions returning\n// field bags, same convention as calendarUtils.ts/comparison.ts — no\n// Temporal namespace needed. Callers can pass the result back into a\n// Temporal constructor to get a typed value, or chain operations\n// without committing to a Temporal implementation.\n\nimport { asDateFieldView, daysInMonth, type DateFieldView } from './calendarUtils.js';\n\nexport type AddUnit = 'years' | 'months' | 'weeks' | 'days' | 'hours' | 'minutes' | 'seconds' | 'milliseconds';\n\ninterface DateTimeFieldView extends DateFieldView {\n hour?: number;\n minute?: number;\n second?: number;\n millisecond?: number;\n}\n\nfunction asDateTime(value: unknown): DateTimeFieldView {\n return asDateFieldView(value) as DateTimeFieldView;\n}\n\n// Recomputes dayOfWeek after year/month/day change. Mirrors\n// calendarUtils.ts's recomputeDayOfWeek — same fix, needed here too\n// since add()/subtract() mutate the date fields via a shallow spread\n// that otherwise leaves the old dayOfWeek sitting there, silently wrong.\nfunction recomputeDayOfWeek(view: DateTimeFieldView): void {\n if (typeof view.dayOfWeek !== 'number') return;\n /* c8 ignore start @preserve -- unreachable: every call site (add()'s\n 'years'/'months' cases, shiftDays()) passes a `result` whose\n year/month/day were just explicitly set, and the value originally\n came from asDateTime()/asDateFieldView(), which throws unless\n year/month/day are all present as numbers. So by the time this guard\n runs, all three are guaranteed valid. Kept in case a future caller\n constructs a DateTimeFieldView bypassing that validation. */\n if (typeof view.year !== 'number' || typeof view.month !== 'number' || typeof view.day !== 'number') return;\n /* c8 ignore stop @preserve */\n const jsDow = new Date(Date.UTC(view.year, view.month - 1, view.day)).getUTCDay(); // 0=Sun..6=Sat\n view.dayOfWeek = jsDow === 0 ? 7 : jsDow; // 1=Mon..7=Sun\n}\n\n// Adds the requested amount to the value's specified unit. Returns a\n// new field bag; the input is not mutated. Handles month/year overflow\n// by clamping to the last valid day of the target month (Feb 29 + 1\n// year on a non-leap year → Feb 28) — Temporal's `constrain` overflow\n// mode, which is the closest match to \"do the obvious thing\" callers\n// expect from arithmetic.\nexport function add(value: unknown, amount: number, unit: AddUnit): DateTimeFieldView {\n const v = asDateTime(value);\n let result: DateTimeFieldView = { ...v };\n switch (unit) {\n case 'years': {\n /* c8 ignore start @preserve -- the `?? 0` fallback is unreachable:\n asDateTime()/asDateFieldView() (called at the top of add()) throws\n unless year is present as a number, so result.year is never\n undefined here. Kept as a guard against a future change that\n relaxes that validation. */\n result.year = (result.year ?? 0) + amount;\n /* c8 ignore stop @preserve */\n // Clamp day-of-month to the new month's length.\n const maxDay = daysInMonth({ year: result.year!, month: result.month! });\n if (result.day! > maxDay) result.day = maxDay;\n recomputeDayOfWeek(result);\n break;\n }\n case 'months': {\n // Total months = year*12 + month + amount, then split back.\n /* c8 ignore start @preserve -- both `??` fallbacks are unreachable\n for the same reason as the 'years' case above: asDateFieldView()\n guarantees year and month are present numbers before add() ever\n reaches here. */\n const total = (result.year ?? 0) * 12 + (result.month ?? 1) - 1 + amount;\n /* c8 ignore stop @preserve */\n result.year = Math.floor(total / 12);\n result.month = (total % 12) + 1;\n if (result.month < 1) { result.month += 12; result.year -= 1; }\n // Negative modulo handling: when total < 0, the mod goes negative.\n // Re-normalize.\n /* c8 ignore start @preserve -- unreachable: (total % 12) + 1 can never\n exceed 12 for any integer total in JS (its range is [-10, 12] since\n JS's % can return a negative remainder but never one with\n magnitude >= 12, so adding 1 tops out at 12). Only the < 1 branch\n above is reachable; this was written symmetrically with it but the\n overflow direction it guards against can't occur. Kept rather than\n removed since it costs nothing and documents the intent. */\n if (result.month > 12) { result.month -= 12; result.year += 1; }\n /* c8 ignore stop @preserve */\n const maxDay = daysInMonth({ year: result.year!, month: result.month! });\n if (result.day! > maxDay) result.day = maxDay;\n recomputeDayOfWeek(result);\n break;\n }\n case 'weeks':\n result = shiftDays(result, amount * 7);\n break;\n case 'days':\n result = shiftDays(result, amount);\n break;\n case 'hours':\n result = shiftTime(result, amount * 3_600_000);\n break;\n case 'minutes':\n result = shiftTime(result, amount * 60_000);\n break;\n case 'seconds':\n result = shiftTime(result, amount * 1_000);\n break;\n case 'milliseconds':\n result = shiftTime(result, amount);\n break;\n }\n return result;\n}\n\nfunction shiftDays(v: DateTimeFieldView, days: number): DateTimeFieldView {\n // Convert Y/M/D to a day count, add, convert back. Using the same\n // algorithm as comparison.ts's sameWeek helper — proleptic Gregorian\n // day count via Howard Hinnant's era-based formula.\n const y = v.year!, m = v.month!, d = v.day!;\n const y2 = m <= 2 ? y - 1 : y;\n const era = Math.floor((y2 >= 0 ? y2 : y2 - 399) / 400);\n const yoe = y2 - era * 400;\n const m2 = m > 2 ? m - 3 : m + 9;\n const doy = Math.floor((153 * m2 + 2) / 5) + d - 1;\n const doe = yoe * 365 + Math.floor(yoe / 4) - Math.floor(yoe / 100) + doy;\n const totalDays = era * 146097 + doe - 719468 + days;\n\n // Invert: totalDays → Y/M/D. Same source (Howard Hinnant's days_from_civil).\n const z = totalDays + 719468;\n const era2 = Math.floor((z >= 0 ? z : z - 146096) / 146097);\n const doe2 = z - era2 * 146097;\n const yoe2 = Math.floor((doe2 - Math.floor(doe2 / 1460) + Math.floor(doe2 / 36524) - Math.floor(doe2 / 146096)) / 365);\n const y2out = yoe2 + era2 * 400;\n const doy2 = doe2 - (365 * yoe2 + Math.floor(yoe2 / 4) - Math.floor(yoe2 / 100));\n const mp = Math.floor((5 * doy2 + 2) / 153);\n const d2 = doy2 - Math.floor((153 * mp + 2) / 5) + 1;\n const m2out = mp < 10 ? mp + 3 : mp - 9;\n const yOut = m2out <= 2 ? y2out + 1 : y2out;\n\n const result: DateTimeFieldView = { ...v, year: yOut, month: m2out, day: d2 };\n recomputeDayOfWeek(result);\n return result;\n}\n\nfunction shiftTime(v: DateTimeFieldView, msDelta: number): DateTimeFieldView {\n // Convert all time fields to ms, add, then split back. Day overflow\n // propagates to shiftDays; sub-second precision is preserved (caller\n // asking for hours/minutes/seconds/milliseconds gets ms-resolution\n // arithmetic, which is the limit of these helpers — nanoseconds\n // aren't supported here, only via Temporal.Duration's own add).\n const MS_PER_DAY = 86_400_000;\n const MS_PER_HOUR = 3_600_000;\n const MS_PER_MINUTE = 60_000;\n const MS_PER_SECOND = 1_000;\n\n const totalMs = (v.hour ?? 0) * MS_PER_HOUR\n + (v.minute ?? 0) * MS_PER_MINUTE\n + (v.second ?? 0) * MS_PER_SECOND\n + (v.millisecond ?? 0)\n + msDelta;\n\n // Split into day-overflow + within-day ms.\n const dayOverflow = Math.floor(totalMs / MS_PER_DAY);\n let withinDay = totalMs % MS_PER_DAY;\n if (withinDay < 0) { withinDay += MS_PER_DAY; }\n\n const hour = Math.floor(withinDay / MS_PER_HOUR);\n const minute = Math.floor((withinDay % MS_PER_HOUR) / MS_PER_MINUTE);\n const second = Math.floor((withinDay % MS_PER_MINUTE) / MS_PER_SECOND);\n const millisecond = withinDay % MS_PER_SECOND;\n\n const result: DateTimeFieldView = { ...v, hour, minute, second, millisecond };\n if (dayOverflow !== 0) {\n return shiftDays(result, dayOverflow);\n }\n return result;\n}\n\nexport function subtract(value: unknown, amount: number, unit: AddUnit): DateTimeFieldView {\n return add(value, -amount, unit);\n}\n\n// Per-unit convenience wrappers — matches the grouping of\n// addYears / addMonths / ... / subtractNanoseconds. Nanosecond variants\n// aren't provided here because these helpers operate on field bags, and\n// the millisecond/microsecond/nanosecond split isn't preserved through\n// arithmetic at sub-millisecond precision the way Temporal.Duration's\n// own add preserves it. For ns-precision arithmetic, use Temporal.Duration\n// directly.\nexport const addYears = (v: unknown, n: number) => add(v, n, 'years');\nexport const addMonths = (v: unknown, n: number) => add(v, n, 'months');\nexport const addWeeks = (v: unknown, n: number) => add(v, n, 'weeks');\nexport const addDays = (v: unknown, n: number) => add(v, n, 'days');\nexport const addHours = (v: unknown, n: number) => add(v, n, 'hours');\nexport const addMinutes = (v: unknown, n: number) => add(v, n, 'minutes');\nexport const addSeconds = (v: unknown, n: number) => add(v, n, 'seconds');\nexport const addMilliseconds = (v: unknown, n: number) => add(v, n, 'milliseconds');\n\nexport const subtractYears = (v: unknown, n: number) => subtract(v, n, 'years');\nexport const subtractMonths = (v: unknown, n: number) => subtract(v, n, 'months');\nexport const subtractWeeks = (v: unknown, n: number) => subtract(v, n, 'weeks');\nexport const subtractDays = (v: unknown, n: number) => subtract(v, n, 'days');\nexport const subtractHours = (v: unknown, n: number) => subtract(v, n, 'hours');\nexport const subtractMinutes = (v: unknown, n: number) => subtract(v, n, 'minutes');\nexport const subtractSeconds = (v: unknown, n: number) => subtract(v, n, 'seconds');\nexport const subtractMilliseconds = (v: unknown, n: number) => subtract(v, n, 'milliseconds');\n\n// difference(): returns the count of `unit` boundaries between two values.\n// Pure-integer math, no Temporal.Duration involved. For sub-day\n// precision the result is an integer count of the requested unit (not\n// a Duration field bag) — matches the most common caller expectation\n// (\"how many days between these two dates?\").\nexport type DiffUnit = 'years' | 'months' | 'weeks' | 'days' | 'hours' | 'minutes' | 'seconds' | 'milliseconds';\n\nexport function difference(a: unknown, b: unknown, unit: DiffUnit): number {\n const av = asDateTime(a);\n const bv = asDateTime(b);\n\n // For day-granular units (years/months/weeks/days), compute via\n // calendar arithmetic on the date fields. For sub-day units, compute\n // via total-ms and divide.\n if (unit === 'years') {\n return bv.year! - av.year!;\n }\n if (unit === 'months') {\n return (bv.year! * 12 + bv.month! - 1) - (av.year! * 12 + av.month! - 1);\n }\n if (unit === 'weeks' || unit === 'days') {\n const aDays = toDayCount(av);\n const bDays = toDayCount(bv);\n const days = bDays - aDays;\n return unit === 'weeks' ? Math.trunc(days / 7) : days;\n }\n\n // Sub-day units: total-ms math.\n const MS_PER_HOUR = 3_600_000;\n const MS_PER_MINUTE = 60_000;\n const MS_PER_SECOND = 1_000;\n const aMs = toTotalMs(av);\n const bMs = toTotalMs(bv);\n const diffMs = bMs - aMs;\n switch (unit) {\n case 'hours': return Math.trunc(diffMs / MS_PER_HOUR);\n case 'minutes': return Math.trunc(diffMs / MS_PER_MINUTE);\n case 'seconds': return Math.trunc(diffMs / MS_PER_SECOND);\n case 'milliseconds': return diffMs;\n }\n}\n\nfunction toDayCount(v: DateTimeFieldView): number {\n const y = v.year!, m = v.month!, d = v.day!;\n const y2 = m <= 2 ? y - 1 : y;\n const era = Math.floor((y2 >= 0 ? y2 : y2 - 399) / 400);\n const yoe = y2 - era * 400;\n const m2 = m > 2 ? m - 3 : m + 9;\n const doy = Math.floor((153 * m2 + 2) / 5) + d - 1;\n const doe = yoe * 365 + Math.floor(yoe / 4) - Math.floor(yoe / 100) + doy;\n return era * 146097 + doe - 719468;\n}\n\nfunction toTotalMs(v: DateTimeFieldView): number {\n const MS_PER_DAY = 86_400_000;\n const MS_PER_HOUR = 3_600_000;\n const MS_PER_MINUTE = 60_000;\n const MS_PER_SECOND = 1_000;\n return toDayCount(v) * MS_PER_DAY\n + (v.hour ?? 0) * MS_PER_HOUR\n + (v.minute ?? 0) * MS_PER_MINUTE\n + (v.second ?? 0) * MS_PER_SECOND\n + (v.millisecond ?? 0);\n}\n\n// Per-unit difference wrappers — same convenience pattern as the add*\n// wrappers above.\nexport const differenceInYears = (a: unknown, b: unknown) => difference(a, b, 'years');\nexport const differenceInMonths = (a: unknown, b: unknown) => difference(a, b, 'months');\nexport const differenceInWeeks = (a: unknown, b: unknown) => difference(a, b, 'weeks');\nexport const differenceInDays = (a: unknown, b: unknown) => difference(a, b, 'days');\nexport const differenceInHours = (a: unknown, b: unknown) => difference(a, b, 'hours');\nexport const differenceInMinutes = (a: unknown, b: unknown) => difference(a, b, 'minutes');\nexport const differenceInSeconds = (a: unknown, b: unknown) => difference(a, b, 'seconds');\nexport const differenceInMilliseconds = (a: unknown, b: unknown) => difference(a, b, 'milliseconds');"],"mappings":"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","names":["asDateTime","value","asDateFieldView","recomputeDayOfWeek","view","jsDow","add","amount","unit","result","maxDay","daysInMonth","total","shiftDays","shiftTime","v","days","y","m","d","y2","era","yoe","m2","doy","doe","z","era2","doe2","yoe2","y2out","doy2","mp","d2","m2out","yOut","msDelta","totalMs","dayOverflow","withinDay","hour","minute","second","millisecond","subtract","addYears","n","addMonths","addWeeks","addDays","addHours","addMinutes","addSeconds","addMilliseconds","subtractYears","subtractMonths","subtractWeeks","subtractDays","subtractHours","subtractMinutes","subtractSeconds","subtractMilliseconds","difference","a","b","av","bv","aDays","toDayCount","MS_PER_HOUR","MS_PER_MINUTE","MS_PER_SECOND","aMs","toTotalMs","diffMs","differenceInYears","differenceInMonths","differenceInWeeks","differenceInDays","differenceInHours","differenceInMinutes","differenceInSeconds","differenceInMilliseconds"]}
1
+ {"version":3,"sources":["../src/arithmetic.ts"],"sourcesContent":["// Date arithmetic helpers. Pure functions returning\n// field bags, same convention as calendarUtils.ts/comparison.ts — no\n// Temporal namespace needed. Callers can pass the result back into a\n// Temporal constructor to get a typed value, or chain operations\n// without committing to a Temporal implementation.\n\nimport { asDateFieldView, daysInMonth, type DateFieldView } from './calendarUtils.js';\n\nexport type AddUnit = 'years' | 'months' | 'weeks' | 'days' | 'hours' | 'minutes' | 'seconds' | 'milliseconds';\n\ninterface DateTimeFieldView extends DateFieldView {\n hour?: number;\n minute?: number;\n second?: number;\n millisecond?: number;\n}\n\nfunction asDateTime(value: unknown): DateTimeFieldView {\n return asDateFieldView(value) as DateTimeFieldView;\n}\n\n// Recomputes dayOfWeek after year/month/day change. Mirrors\n// calendarUtils.ts's recomputeDayOfWeek — same fix, needed here too\n// since add()/subtract() mutate the date fields via a shallow spread\n// that otherwise leaves the old dayOfWeek sitting there, silently wrong.\nfunction recomputeDayOfWeek(view: DateTimeFieldView): void {\n if (typeof view.dayOfWeek !== 'number') return;\n /* c8 ignore start @preserve -- unreachable: every call site (add()'s\n 'years'/'months' cases, shiftDays()) passes a `result` whose\n year/month/day were just explicitly set, and the value originally\n came from asDateTime()/asDateFieldView(), which throws unless\n year/month/day are all present as numbers. So by the time this guard\n runs, all three are guaranteed valid. Kept in case a future caller\n constructs a DateTimeFieldView bypassing that validation. */\n if (typeof view.year !== 'number' || typeof view.month !== 'number' || typeof view.day !== 'number') return;\n /* c8 ignore stop @preserve */\n const jsDow = new Date(Date.UTC(view.year, view.month - 1, view.day)).getUTCDay(); // 0=Sun..6=Sat\n view.dayOfWeek = jsDow === 0 ? 7 : jsDow; // 1=Mon..7=Sun\n}\n\n// Adds the requested amount to the value's specified unit. Returns a\n// new field bag; the input is not mutated. Handles month/year overflow\n// by clamping to the last valid day of the target month (Feb 29 + 1\n// year on a non-leap year → Feb 28) — Temporal's `constrain` overflow\n// mode, which is the closest match to \"do the obvious thing\" callers\n// expect from arithmetic.\nexport function add(value: unknown, amount: number, unit: AddUnit): DateTimeFieldView {\n const v = asDateTime(value);\n let result: DateTimeFieldView = { ...v };\n switch (unit) {\n case 'years': {\n /* c8 ignore start @preserve -- the `?? 0` fallback is unreachable:\n asDateTime()/asDateFieldView() (called at the top of add()) throws\n unless year is present as a number, so result.year is never\n undefined here. Kept as a guard against a future change that\n relaxes that validation. */\n result.year = (result.year ?? 0) + amount;\n /* c8 ignore stop @preserve */\n // Clamp day-of-month to the new month's length.\n const maxDay = daysInMonth({ year: result.year!, month: result.month! });\n if (result.day! > maxDay) result.day = maxDay;\n recomputeDayOfWeek(result);\n break;\n }\n case 'months': {\n // Total months = year*12 + month + amount, then split back.\n /* c8 ignore start @preserve -- both `??` fallbacks are unreachable\n for the same reason as the 'years' case above: asDateFieldView()\n guarantees year and month are present numbers before add() ever\n reaches here. */\n const total = (result.year ?? 0) * 12 + (result.month ?? 1) - 1 + amount;\n /* c8 ignore stop @preserve */\n result.year = Math.floor(total / 12);\n result.month = (total % 12) + 1;\n if (result.month < 1) { result.month += 12; result.year -= 1; }\n // Negative modulo handling: when total < 0, the mod goes negative.\n // Re-normalize.\n /* c8 ignore start @preserve -- unreachable: (total % 12) + 1 can never\n exceed 12 for any integer total in JS (its range is [-10, 12] since\n JS's % can return a negative remainder but never one with\n magnitude >= 12, so adding 1 tops out at 12). Only the < 1 branch\n above is reachable; this was written symmetrically with it but the\n overflow direction it guards against can't occur. Kept rather than\n removed since it costs nothing and documents the intent. */\n if (result.month > 12) { result.month -= 12; result.year += 1; }\n /* c8 ignore stop @preserve */\n const maxDay = daysInMonth({ year: result.year!, month: result.month! });\n if (result.day! > maxDay) result.day = maxDay;\n recomputeDayOfWeek(result);\n break;\n }\n case 'weeks':\n result = shiftDays(result, amount * 7);\n break;\n case 'days':\n result = shiftDays(result, amount);\n break;\n case 'hours':\n result = shiftTime(result, amount * 3_600_000);\n break;\n case 'minutes':\n result = shiftTime(result, amount * 60_000);\n break;\n case 'seconds':\n result = shiftTime(result, amount * 1_000);\n break;\n case 'milliseconds':\n result = shiftTime(result, amount);\n break;\n }\n return result;\n}\n\nfunction shiftDays(v: DateTimeFieldView, days: number): DateTimeFieldView {\n // Convert Y/M/D to a day count, add, convert back. Using the same\n // algorithm as comparison.ts's sameWeek helper — proleptic Gregorian\n // day count via Howard Hinnant's era-based formula.\n const y = v.year!, m = v.month!, d = v.day!;\n const y2 = m <= 2 ? y - 1 : y;\n const era = Math.floor((y2 >= 0 ? y2 : y2 - 399) / 400);\n const yoe = y2 - era * 400;\n const m2 = m > 2 ? m - 3 : m + 9;\n const doy = Math.floor((153 * m2 + 2) / 5) + d - 1;\n const doe = yoe * 365 + Math.floor(yoe / 4) - Math.floor(yoe / 100) + doy;\n const totalDays = era * 146097 + doe - 719468 + days;\n\n // Invert: totalDays → Y/M/D. Same source (Howard Hinnant's days_from_civil).\n const z = totalDays + 719468;\n const era2 = Math.floor((z >= 0 ? z : z - 146096) / 146097);\n const doe2 = z - era2 * 146097;\n const yoe2 = Math.floor((doe2 - Math.floor(doe2 / 1460) + Math.floor(doe2 / 36524) - Math.floor(doe2 / 146096)) / 365);\n const y2out = yoe2 + era2 * 400;\n const doy2 = doe2 - (365 * yoe2 + Math.floor(yoe2 / 4) - Math.floor(yoe2 / 100));\n const mp = Math.floor((5 * doy2 + 2) / 153);\n const d2 = doy2 - Math.floor((153 * mp + 2) / 5) + 1;\n const m2out = mp < 10 ? mp + 3 : mp - 9;\n const yOut = m2out <= 2 ? y2out + 1 : y2out;\n\n const result: DateTimeFieldView = { ...v, year: yOut, month: m2out, day: d2 };\n recomputeDayOfWeek(result);\n return result;\n}\n\nfunction shiftTime(v: DateTimeFieldView, msDelta: number): DateTimeFieldView {\n // Convert all time fields to ms, add, then split back. Day overflow\n // propagates to shiftDays; sub-second precision is preserved (caller\n // asking for hours/minutes/seconds/milliseconds gets ms-resolution\n // arithmetic, which is the limit of these helpers — nanoseconds\n // aren't supported here, only via Temporal.Duration's own add).\n const MS_PER_DAY = 86_400_000;\n const MS_PER_HOUR = 3_600_000;\n const MS_PER_MINUTE = 60_000;\n const MS_PER_SECOND = 1_000;\n\n const totalMs = (v.hour ?? 0) * MS_PER_HOUR\n + (v.minute ?? 0) * MS_PER_MINUTE\n + (v.second ?? 0) * MS_PER_SECOND\n + (v.millisecond ?? 0)\n + msDelta;\n\n // Split into day-overflow + within-day ms.\n const dayOverflow = Math.floor(totalMs / MS_PER_DAY);\n let withinDay = totalMs % MS_PER_DAY;\n if (withinDay < 0) { withinDay += MS_PER_DAY; }\n\n const hour = Math.floor(withinDay / MS_PER_HOUR);\n const minute = Math.floor((withinDay % MS_PER_HOUR) / MS_PER_MINUTE);\n const second = Math.floor((withinDay % MS_PER_MINUTE) / MS_PER_SECOND);\n const millisecond = withinDay % MS_PER_SECOND;\n\n const result: DateTimeFieldView = { ...v, hour, minute, second, millisecond };\n if (dayOverflow !== 0) {\n return shiftDays(result, dayOverflow);\n }\n return result;\n}\n\nexport function subtract(value: unknown, amount: number, unit: AddUnit): DateTimeFieldView {\n return add(value, -amount, unit);\n}\n\n// Per-unit convenience wrappers — matches the grouping of\n// addYears / addMonths / ... / subtractNanoseconds. Nanosecond variants\n// aren't provided here because these helpers operate on field bags, and\n// the millisecond/microsecond/nanosecond split isn't preserved through\n// arithmetic at sub-millisecond precision the way Temporal.Duration's\n// own add preserves it. For ns-precision arithmetic, use Temporal.Duration\n// directly.\nexport const addYears = (v: unknown, n: number) => add(v, n, 'years');\nexport const addMonths = (v: unknown, n: number) => add(v, n, 'months');\nexport const addWeeks = (v: unknown, n: number) => add(v, n, 'weeks');\nexport const addDays = (v: unknown, n: number) => add(v, n, 'days');\nexport const addHours = (v: unknown, n: number) => add(v, n, 'hours');\nexport const addMinutes = (v: unknown, n: number) => add(v, n, 'minutes');\nexport const addSeconds = (v: unknown, n: number) => add(v, n, 'seconds');\nexport const addMilliseconds = (v: unknown, n: number) => add(v, n, 'milliseconds');\n\nexport const subtractYears = (v: unknown, n: number) => subtract(v, n, 'years');\nexport const subtractMonths = (v: unknown, n: number) => subtract(v, n, 'months');\nexport const subtractWeeks = (v: unknown, n: number) => subtract(v, n, 'weeks');\nexport const subtractDays = (v: unknown, n: number) => subtract(v, n, 'days');\nexport const subtractHours = (v: unknown, n: number) => subtract(v, n, 'hours');\nexport const subtractMinutes = (v: unknown, n: number) => subtract(v, n, 'minutes');\nexport const subtractSeconds = (v: unknown, n: number) => subtract(v, n, 'seconds');\nexport const subtractMilliseconds = (v: unknown, n: number) => subtract(v, n, 'milliseconds');\n\n// difference(): returns the count of `unit` boundaries between two values.\n// Pure-integer math, no Temporal.Duration involved. For sub-day\n// precision the result is an integer count of the requested unit (not\n// a Duration field bag) — matches the most common caller expectation\n// (\"how many days between these two dates?\").\nexport type DiffUnit = 'years' | 'months' | 'weeks' | 'days' | 'hours' | 'minutes' | 'seconds' | 'milliseconds';\n\nexport function difference(a: unknown, b: unknown, unit: DiffUnit): number {\n const av = asDateTime(a);\n const bv = asDateTime(b);\n\n // For day-granular units (years/months/weeks/days), compute via\n // calendar arithmetic on the date fields. For sub-day units, compute\n // via total-ms and divide.\n if (unit === 'years') {\n return bv.year! - av.year!;\n }\n if (unit === 'months') {\n return (bv.year! * 12 + bv.month! - 1) - (av.year! * 12 + av.month! - 1);\n }\n if (unit === 'weeks' || unit === 'days') {\n const aDays = toDayCount(av);\n const bDays = toDayCount(bv);\n const days = bDays - aDays;\n return unit === 'weeks' ? Math.trunc(days / 7) : days;\n }\n\n // Sub-day units: total-ms math.\n const MS_PER_HOUR = 3_600_000;\n const MS_PER_MINUTE = 60_000;\n const MS_PER_SECOND = 1_000;\n const aMs = toTotalMs(av);\n const bMs = toTotalMs(bv);\n const diffMs = bMs - aMs;\n switch (unit) {\n case 'hours': return Math.trunc(diffMs / MS_PER_HOUR);\n case 'minutes': return Math.trunc(diffMs / MS_PER_MINUTE);\n case 'seconds': return Math.trunc(diffMs / MS_PER_SECOND);\n case 'milliseconds': return diffMs;\n }\n}\n\nfunction toDayCount(v: DateTimeFieldView): number {\n const y = v.year!, m = v.month!, d = v.day!;\n const y2 = m <= 2 ? y - 1 : y;\n const era = Math.floor((y2 >= 0 ? y2 : y2 - 399) / 400);\n const yoe = y2 - era * 400;\n const m2 = m > 2 ? m - 3 : m + 9;\n const doy = Math.floor((153 * m2 + 2) / 5) + d - 1;\n const doe = yoe * 365 + Math.floor(yoe / 4) - Math.floor(yoe / 100) + doy;\n return era * 146097 + doe - 719468;\n}\n\nfunction toTotalMs(v: DateTimeFieldView): number {\n const MS_PER_DAY = 86_400_000;\n const MS_PER_HOUR = 3_600_000;\n const MS_PER_MINUTE = 60_000;\n const MS_PER_SECOND = 1_000;\n return toDayCount(v) * MS_PER_DAY\n + (v.hour ?? 0) * MS_PER_HOUR\n + (v.minute ?? 0) * MS_PER_MINUTE\n + (v.second ?? 0) * MS_PER_SECOND\n + (v.millisecond ?? 0);\n}\n\n// Per-unit difference wrappers — same convenience pattern as the add*\n// wrappers above.\nexport const differenceInYears = (a: unknown, b: unknown) => difference(a, b, 'years');\nexport const differenceInMonths = (a: unknown, b: unknown) => difference(a, b, 'months');\nexport const differenceInWeeks = (a: unknown, b: unknown) => difference(a, b, 'weeks');\nexport const differenceInDays = (a: unknown, b: unknown) => difference(a, b, 'days');\nexport const differenceInHours = (a: unknown, b: unknown) => difference(a, b, 'hours');\nexport const differenceInMinutes = (a: unknown, b: unknown) => difference(a, b, 'minutes');\nexport const differenceInSeconds = (a: unknown, b: unknown) => difference(a, b, 'seconds');\nexport const differenceInMilliseconds = (a: unknown, b: unknown) => difference(a, b, 'milliseconds');"],"mappings":"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","names":[]}
@@ -0,0 +1,75 @@
1
+ import {
2
+ InvalidLocaleError,
3
+ getLocaleVocab,
4
+ registerLocaleVocab
5
+ } from "./chunk-EGUUO6LE.js";
6
+
7
+ // src/localeRegistry.ts
8
+ var extendedVocabs = /* @__PURE__ */ new Map();
9
+ var MAX_LOCALE_TAG_LENGTH = 256;
10
+ var MAX_VOCAB_STRING_LENGTH = 256;
11
+ function canonicalKey(locale) {
12
+ try {
13
+ return new Intl.Locale(locale.replace(/_/g, "-")).toString().toLowerCase();
14
+ } catch {
15
+ return locale;
16
+ }
17
+ }
18
+ function registerLocale(locale, vocab) {
19
+ if (typeof locale !== "string" || locale.length === 0) {
20
+ throw new InvalidLocaleError({ actual: String(locale), reason: "locale string must be non-empty" });
21
+ }
22
+ if (locale.length > MAX_LOCALE_TAG_LENGTH) {
23
+ throw new InvalidLocaleError({ actual: String(locale.length), reason: `locale tag must be at most ${MAX_LOCALE_TAG_LENGTH} characters` });
24
+ }
25
+ registerLocaleVocab(locale, vocab);
26
+ validateExtended(vocab, locale);
27
+ const key = canonicalKey(locale);
28
+ extendedVocabs.set(key, { ...vocab });
29
+ }
30
+ function validateExtended(vocab, locale) {
31
+ const checkArray = (val, key, length) => {
32
+ if (val === void 0) return;
33
+ if (!Array.isArray(val)) {
34
+ throw new InvalidLocaleError({ actual: String(val), reason: `locale "${locale}": "${key}" must be an array` });
35
+ }
36
+ if (val.length !== length) {
37
+ throw new InvalidLocaleError({ actual: String(val.length), reason: `locale "${locale}": "${key}" must have ${length} entries (got ${val.length})` });
38
+ }
39
+ for (let i = 0; i < val.length; i++) {
40
+ if (typeof val[i] !== "string" || val[i].length === 0) {
41
+ throw new InvalidLocaleError({ actual: String(val[i]), reason: `locale "${locale}": "${key}[${i}]" must be a non-empty string` });
42
+ }
43
+ if (val[i].length > MAX_VOCAB_STRING_LENGTH) {
44
+ throw new InvalidLocaleError({ actual: String(val[i].length), reason: `locale "${locale}": "${key}[${i}]" must be at most ${MAX_VOCAB_STRING_LENGTH} characters` });
45
+ }
46
+ }
47
+ };
48
+ checkArray(vocab.quartersLong, "quartersLong", 4);
49
+ checkArray(vocab.quartersShort, "quartersShort", 4);
50
+ checkArray(vocab.erasLong, "erasLong", 2);
51
+ checkArray(vocab.erasShort, "erasShort", 2);
52
+ checkArray(vocab.ordinals, "ordinals", 4);
53
+ }
54
+ function getLocale(locale) {
55
+ const key = canonicalKey(locale);
56
+ const ext = extendedVocabs.get(key);
57
+ if (ext) return ext;
58
+ try {
59
+ const base = getLocaleVocab(locale);
60
+ return { ...base };
61
+ } catch {
62
+ return void 0;
63
+ }
64
+ }
65
+ function hasLocale(locale) {
66
+ const key = canonicalKey(locale);
67
+ return extendedVocabs.has(key);
68
+ }
69
+
70
+ export {
71
+ registerLocale,
72
+ getLocale,
73
+ hasLocale
74
+ };
75
+ //# sourceMappingURL=chunk-UOPAV3WX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/localeRegistry.ts"],"sourcesContent":["// locale registration + lookup. builds on the registerLocaleVocab()\n// stuff already in localeVocab.ts, adds registerLocale() / getLocale() /\n// hasLocale() plus a beefier LocaleVocab that covers quarters, eras,\n// ordinals, duration units, and relative-time words.\n//\n// localeVocab.ts itself is unchanged and still handles months/weekdays/\n// day-periods (what tokens.ts reads for MMMM/MMM/EEEE/EEE/a). this module\n// just wraps that and bolts the extra fields on top\n\nimport { registerLocaleVocab, getLocaleVocab, type LocaleVocab as BaseLocaleVocab } from './localeVocab.js';\nimport { InvalidLocaleError } from './errors.js';\n\nexport interface ExtendedLocaleVocab extends BaseLocaleVocab {\n // Q1-Q4 long form (\"First quarter\" etc). falls back to \"Q1\"..\"Q4\" if\n // nothing's registered\n quartersLong?: string[];\n quartersShort?: string[];\n // like [\"BC\", \"AD\"] for gregory. defaults to [\"BC\", \"AD\"]\n erasLong?: string[];\n erasShort?: string[];\n // suffixes like [\"st\", \"nd\", \"rd\", \"th\"] for English. empty by default —\n // the 'do' token already has English ordinal logic hardcoded in\n // tokens.ts, this just lets a custom locale override that\n ordinals?: string[];\n // long singular/plural names per unit. used by formatDuration's\n // locale-aware path for cases where Intl.NumberFormat won't cut it,\n // like a made-up locale Intl's never heard of\n durationUnits?: {\n years: [string, string];\n months: [string, string];\n weeks: [string, string];\n days: [string, string];\n hours: [string, string];\n minutes: [string, string];\n seconds: [string, string];\n milliseconds: [string, string];\n };\n // words for \"ago\" / \"in\" / \"now\". used by formatRelative()'s\n // locale-aware path when Intl.RelativeTimeFormat isn't around or\n // doesn't know about a locale someone registered\n relativeTime?: {\n past: string;\n future: string;\n now: string;\n };\n}\n\n// bounded indirectly — everything added here goes through registerLocale(),\n// which calls registerLocaleVocab() first, and THAT registry already caps\n// out at 500 new locales (MAX_CUSTOM_VOCABS, throws RangeError past it).\n// so extendedVocabs can never actually exceed 500 keys, no need for a\n// separate cap here (would just be dead code anyway)\nconst extendedVocabs = new Map<string, ExtendedLocaleVocab>();\nconst MAX_LOCALE_TAG_LENGTH = 256;\nconst MAX_VOCAB_STRING_LENGTH = 256;\n\nfunction canonicalKey(locale: string): string {\n try {\n return new Intl.Locale(locale.replace(/_/g, '-')).toString().toLowerCase();\n } catch {\n return locale;\n }\n}\n\nexport function registerLocale(locale: string, vocab: ExtendedLocaleVocab): void {\n if (typeof locale !== 'string' || locale.length === 0) {\n throw new InvalidLocaleError({ actual: String(locale), reason: 'locale string must be non-empty' });\n }\n if (locale.length > MAX_LOCALE_TAG_LENGTH) {\n throw new InvalidLocaleError({ actual: String(locale.length), reason: `locale tag must be at most ${MAX_LOCALE_TAG_LENGTH} characters` });\n }\n // base vocab fields (months/weekdays/day-periods) get validated by\n // registerLocaleVocab already, it's got the strict shape checks\n registerLocaleVocab(locale, vocab);\n // extended fields are all optional, only check the ones actually there\n validateExtended(vocab, locale);\n const key = canonicalKey(locale);\n extendedVocabs.set(key, { ...vocab });\n}\n\nfunction validateExtended(vocab: ExtendedLocaleVocab, locale: string): void {\n const checkArray = (val: unknown, key: string, length: number) => {\n if (val === undefined) return;\n if (!Array.isArray(val)) {\n throw new InvalidLocaleError({ actual: String(val), reason: `locale \"${locale}\": \"${key}\" must be an array` });\n }\n if (val.length !== length) {\n throw new InvalidLocaleError({ actual: String(val.length), reason: `locale \"${locale}\": \"${key}\" must have ${length} entries (got ${val.length})` });\n }\n for (let i = 0; i < val.length; i++) {\n if (typeof val[i] !== 'string' || val[i]!.length === 0) {\n throw new InvalidLocaleError({ actual: String(val[i]), reason: `locale \"${locale}\": \"${key}[${i}]\" must be a non-empty string` });\n }\n if (val[i]!.length > MAX_VOCAB_STRING_LENGTH) {\n throw new InvalidLocaleError({ actual: String(val[i]!.length), reason: `locale \"${locale}\": \"${key}[${i}]\" must be at most ${MAX_VOCAB_STRING_LENGTH} characters` });\n }\n }\n };\n checkArray(vocab.quartersLong, 'quartersLong', 4);\n checkArray(vocab.quartersShort, 'quartersShort', 4);\n checkArray(vocab.erasLong, 'erasLong', 2);\n checkArray(vocab.erasShort, 'erasShort', 2);\n checkArray(vocab.ordinals, 'ordinals', 4);\n}\n\nexport function getLocale(locale: string): ExtendedLocaleVocab | undefined {\n // gives back the extended vocab for a locale, or undefined if there's\n // nothing (falls back to Intl at that point). combines the base vocab\n // (from localeVocab.ts, Intl-derived) with whatever extended fields\n // got registered here\n const key = canonicalKey(locale);\n const ext = extendedVocabs.get(key);\n if (ext) return ext;\n // nothing extended registered — just fall back to the base Intl vocab\n try {\n const base = getLocaleVocab(locale);\n return { ...base };\n } catch {\n return undefined;\n }\n}\n\nexport function hasLocale(locale: string): boolean {\n const key = canonicalKey(locale);\n return extendedVocabs.has(key);\n}\n\n// re-exporting the base vocab types in case anyone wants them\nexport type { LocaleVocab } from './localeVocab.js';\n"],"mappings":";;;;;;;AAoDA,IAAM,iBAAiB,oBAAI,IAAiC;AAC5D,IAAM,wBAAwB;AAC9B,IAAM,0BAA0B;AAEhC,SAAS,aAAa,QAAwB;AAC5C,MAAI;AACF,WAAO,IAAI,KAAK,OAAO,OAAO,QAAQ,MAAM,GAAG,CAAC,EAAE,SAAS,EAAE,YAAY;AAAA,EAC3E,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,eAAe,QAAgB,OAAkC;AAC/E,MAAI,OAAO,WAAW,YAAY,OAAO,WAAW,GAAG;AACrD,UAAM,IAAI,mBAAmB,EAAE,QAAQ,OAAO,MAAM,GAAG,QAAQ,kCAAkC,CAAC;AAAA,EACpG;AACA,MAAI,OAAO,SAAS,uBAAuB;AACzC,UAAM,IAAI,mBAAmB,EAAE,QAAQ,OAAO,OAAO,MAAM,GAAG,QAAQ,8BAA8B,qBAAqB,cAAc,CAAC;AAAA,EAC1I;AAGA,sBAAoB,QAAQ,KAAK;AAEjC,mBAAiB,OAAO,MAAM;AAC9B,QAAM,MAAM,aAAa,MAAM;AAC/B,iBAAe,IAAI,KAAK,EAAE,GAAG,MAAM,CAAC;AACtC;AAEA,SAAS,iBAAiB,OAA4B,QAAsB;AAC1E,QAAM,aAAa,CAAC,KAAc,KAAa,WAAmB;AAChE,QAAI,QAAQ,OAAW;AACvB,QAAI,CAAC,MAAM,QAAQ,GAAG,GAAG;AACvB,YAAM,IAAI,mBAAmB,EAAE,QAAQ,OAAO,GAAG,GAAG,QAAQ,WAAW,MAAM,OAAO,GAAG,qBAAqB,CAAC;AAAA,IAC/G;AACA,QAAI,IAAI,WAAW,QAAQ;AACzB,YAAM,IAAI,mBAAmB,EAAE,QAAQ,OAAO,IAAI,MAAM,GAAG,QAAQ,WAAW,MAAM,OAAO,GAAG,eAAe,MAAM,iBAAiB,IAAI,MAAM,IAAI,CAAC;AAAA,IACrJ;AACA,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,UAAI,OAAO,IAAI,CAAC,MAAM,YAAY,IAAI,CAAC,EAAG,WAAW,GAAG;AACtD,cAAM,IAAI,mBAAmB,EAAE,QAAQ,OAAO,IAAI,CAAC,CAAC,GAAG,QAAQ,WAAW,MAAM,OAAO,GAAG,IAAI,CAAC,gCAAgC,CAAC;AAAA,MAClI;AACA,UAAI,IAAI,CAAC,EAAG,SAAS,yBAAyB;AAC5C,cAAM,IAAI,mBAAmB,EAAE,QAAQ,OAAO,IAAI,CAAC,EAAG,MAAM,GAAG,QAAQ,WAAW,MAAM,OAAO,GAAG,IAAI,CAAC,sBAAsB,uBAAuB,cAAc,CAAC;AAAA,MACrK;AAAA,IACF;AAAA,EACF;AACA,aAAW,MAAM,cAAc,gBAAgB,CAAC;AAChD,aAAW,MAAM,eAAe,iBAAiB,CAAC;AAClD,aAAW,MAAM,UAAU,YAAY,CAAC;AACxC,aAAW,MAAM,WAAW,aAAa,CAAC;AAC1C,aAAW,MAAM,UAAU,YAAY,CAAC;AAC1C;AAEO,SAAS,UAAU,QAAiD;AAKzE,QAAM,MAAM,aAAa,MAAM;AAC/B,QAAM,MAAM,eAAe,IAAI,GAAG;AAClC,MAAI,IAAK,QAAO;AAEhB,MAAI;AACF,UAAM,OAAO,eAAe,MAAM;AAClC,WAAO,EAAE,GAAG,KAAK;AAAA,EACnB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,UAAU,QAAyB;AACjD,QAAM,MAAM,aAAa,MAAM;AAC/B,SAAO,eAAe,IAAI,GAAG;AAC/B;","names":[]}