@gobrand/tiempo 3.1.3 → 3.2.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 (151) hide show
  1. package/dist/addBusinessDays.d.ts +14 -4
  2. package/dist/addBusinessDays.d.ts.map +1 -1
  3. package/dist/addBusinessDays.js +2 -2
  4. package/dist/areIntervalsOverlapping.d.ts +60 -0
  5. package/dist/areIntervalsOverlapping.d.ts.map +1 -0
  6. package/dist/areIntervalsOverlapping.js +9 -0
  7. package/dist/areIntervalsOverlapping.js.map +1 -0
  8. package/dist/chunk-2JXI3CAL.js +22 -0
  9. package/dist/chunk-2JXI3CAL.js.map +1 -0
  10. package/dist/{chunk-BYPHFTFD.js → chunk-2LT2XOAL.js} +4 -82
  11. package/dist/chunk-2LT2XOAL.js.map +1 -0
  12. package/dist/chunk-3OOGJRXH.js +247 -0
  13. package/dist/chunk-3OOGJRXH.js.map +1 -0
  14. package/dist/chunk-42IFQS4W.js +16 -0
  15. package/dist/chunk-42IFQS4W.js.map +1 -0
  16. package/dist/{chunk-MXYAZTDE.js → chunk-4FQCY75E.js} +4 -4
  17. package/dist/chunk-4YCEFGZA.js +61 -0
  18. package/dist/chunk-4YCEFGZA.js.map +1 -0
  19. package/dist/chunk-6UBFKQIJ.js +20 -0
  20. package/dist/chunk-6UBFKQIJ.js.map +1 -0
  21. package/dist/chunk-7PH5BPMS.js +14 -0
  22. package/dist/chunk-7PH5BPMS.js.map +1 -0
  23. package/dist/chunk-C7QA4J6V.js +14 -0
  24. package/dist/chunk-C7QA4J6V.js.map +1 -0
  25. package/dist/chunk-DVZDJ5LM.js +33 -0
  26. package/dist/chunk-DVZDJ5LM.js.map +1 -0
  27. package/dist/{chunk-AOODDNHA.js → chunk-DYIISNVW.js} +14 -12
  28. package/dist/chunk-DYIISNVW.js.map +1 -0
  29. package/dist/{chunk-6QZUAJVF.js → chunk-GOJ45AG7.js} +2 -2
  30. package/dist/chunk-H43LMOCK.js +26 -0
  31. package/dist/chunk-H43LMOCK.js.map +1 -0
  32. package/dist/chunk-HH2HTC44.js +87 -0
  33. package/dist/chunk-HH2HTC44.js.map +1 -0
  34. package/dist/chunk-IDB3R3G5.js +21 -0
  35. package/dist/chunk-IDB3R3G5.js.map +1 -0
  36. package/dist/chunk-IIEHQPKE.js +36 -0
  37. package/dist/chunk-IIEHQPKE.js.map +1 -0
  38. package/dist/{chunk-OVBZ2NBB.js → chunk-K7SY2MAX.js} +10 -4
  39. package/dist/chunk-K7SY2MAX.js.map +1 -0
  40. package/dist/chunk-KZYWHHAQ.js +19 -0
  41. package/dist/chunk-KZYWHHAQ.js.map +1 -0
  42. package/dist/chunk-M2XB72L5.js +17 -0
  43. package/dist/chunk-M2XB72L5.js.map +1 -0
  44. package/dist/chunk-OMUK2MOH.js +19 -0
  45. package/dist/chunk-OMUK2MOH.js.map +1 -0
  46. package/dist/chunk-PLPGYCQQ.js +28 -0
  47. package/dist/chunk-PLPGYCQQ.js.map +1 -0
  48. package/dist/chunk-R6D3Y5NV.js +17 -0
  49. package/dist/chunk-R6D3Y5NV.js.map +1 -0
  50. package/dist/chunk-U6VFT2A5.js +14 -0
  51. package/dist/chunk-U6VFT2A5.js.map +1 -0
  52. package/dist/chunk-XMEPH226.js +21 -0
  53. package/dist/chunk-XMEPH226.js.map +1 -0
  54. package/dist/{chunk-NGS5UKDW.js → chunk-ZNRTNR2Q.js} +4 -4
  55. package/dist/differenceInBusinessDays.d.ts +7 -5
  56. package/dist/differenceInBusinessDays.d.ts.map +1 -1
  57. package/dist/differenceInBusinessDays.js +2 -2
  58. package/dist/differenceInCalendarDays.d.ts +35 -0
  59. package/dist/differenceInCalendarDays.d.ts.map +1 -0
  60. package/dist/differenceInCalendarDays.js +10 -0
  61. package/dist/differenceInCalendarDays.js.map +1 -0
  62. package/dist/differenceInCalendarMonths.d.ts +27 -0
  63. package/dist/differenceInCalendarMonths.d.ts.map +1 -0
  64. package/dist/differenceInCalendarMonths.js +10 -0
  65. package/dist/differenceInCalendarMonths.js.map +1 -0
  66. package/dist/differenceInCalendarQuarters.d.ts +26 -0
  67. package/dist/differenceInCalendarQuarters.d.ts.map +1 -0
  68. package/dist/differenceInCalendarQuarters.js +11 -0
  69. package/dist/differenceInCalendarQuarters.js.map +1 -0
  70. package/dist/differenceInCalendarWeeks.d.ts +29 -0
  71. package/dist/differenceInCalendarWeeks.d.ts.map +1 -0
  72. package/dist/differenceInCalendarWeeks.js +11 -0
  73. package/dist/differenceInCalendarWeeks.js.map +1 -0
  74. package/dist/differenceInCalendarYears.d.ts +27 -0
  75. package/dist/differenceInCalendarYears.d.ts.map +1 -0
  76. package/dist/differenceInCalendarYears.js +10 -0
  77. package/dist/differenceInCalendarYears.js.map +1 -0
  78. package/dist/eachWeekOfInterval.d.ts +7 -5
  79. package/dist/eachWeekOfInterval.d.ts.map +1 -1
  80. package/dist/eachWeekOfInterval.js +2 -1
  81. package/dist/endOfQuarter.js +2 -2
  82. package/dist/endOfWeek.d.ts +17 -7
  83. package/dist/endOfWeek.d.ts.map +1 -1
  84. package/dist/endOfWeek.js +2 -1
  85. package/dist/format.d.ts.map +1 -1
  86. package/dist/format.js +2 -1
  87. package/dist/index.d.ts +10 -0
  88. package/dist/index.d.ts.map +1 -1
  89. package/dist/index.js +117 -78
  90. package/dist/isSameWeek.d.ts +16 -7
  91. package/dist/isSameWeek.d.ts.map +1 -1
  92. package/dist/isSameWeek.js +2 -1
  93. package/dist/isWeekend.js +2 -2
  94. package/dist/isWithinInterval.d.ts +41 -6
  95. package/dist/isWithinInterval.d.ts.map +1 -1
  96. package/dist/isWithinInterval.js +3 -2
  97. package/dist/nextDay.d.ts +33 -0
  98. package/dist/nextDay.d.ts.map +1 -0
  99. package/dist/nextDay.js +10 -0
  100. package/dist/nextDay.js.map +1 -0
  101. package/dist/parse.d.ts +57 -0
  102. package/dist/parse.d.ts.map +1 -0
  103. package/dist/parse.js +9 -0
  104. package/dist/parse.js.map +1 -0
  105. package/dist/previousDay.d.ts +26 -0
  106. package/dist/previousDay.d.ts.map +1 -0
  107. package/dist/previousDay.js +10 -0
  108. package/dist/previousDay.js.map +1 -0
  109. package/dist/shared/businessDays.d.ts +15 -0
  110. package/dist/shared/businessDays.d.ts.map +1 -1
  111. package/dist/shared/businessDays.js +7 -3
  112. package/dist/shared/calendarDates.d.ts +9 -0
  113. package/dist/shared/calendarDates.d.ts.map +1 -0
  114. package/dist/shared/calendarDates.js +9 -0
  115. package/dist/shared/calendarDates.js.map +1 -0
  116. package/dist/shared/formatTokens.d.ts +8 -0
  117. package/dist/shared/formatTokens.d.ts.map +1 -0
  118. package/dist/shared/formatTokens.js +7 -0
  119. package/dist/shared/formatTokens.js.map +1 -0
  120. package/dist/shared/week.d.ts +26 -0
  121. package/dist/shared/week.d.ts.map +1 -0
  122. package/dist/shared/week.js +9 -0
  123. package/dist/shared/week.js.map +1 -0
  124. package/dist/startOfQuarter.js +2 -2
  125. package/dist/startOfWeek.d.ts +17 -7
  126. package/dist/startOfWeek.d.ts.map +1 -1
  127. package/dist/startOfWeek.js +2 -1
  128. package/dist/subBusinessDays.d.ts +6 -4
  129. package/dist/subBusinessDays.d.ts.map +1 -1
  130. package/dist/subBusinessDays.js +3 -3
  131. package/package.json +1 -1
  132. package/dist/chunk-2TISXHHK.js +0 -29
  133. package/dist/chunk-2TISXHHK.js.map +0 -1
  134. package/dist/chunk-4PS6BEAC.js +0 -16
  135. package/dist/chunk-4PS6BEAC.js.map +0 -1
  136. package/dist/chunk-57MHNRCU.js +0 -22
  137. package/dist/chunk-57MHNRCU.js.map +0 -1
  138. package/dist/chunk-AOODDNHA.js.map +0 -1
  139. package/dist/chunk-BYPHFTFD.js.map +0 -1
  140. package/dist/chunk-D3N7BT44.js +0 -22
  141. package/dist/chunk-D3N7BT44.js.map +0 -1
  142. package/dist/chunk-GCVX5QIX.js +0 -15
  143. package/dist/chunk-GCVX5QIX.js.map +0 -1
  144. package/dist/chunk-K7CLBBBM.js +0 -36
  145. package/dist/chunk-K7CLBBBM.js.map +0 -1
  146. package/dist/chunk-MLHFNZEA.js +0 -26
  147. package/dist/chunk-MLHFNZEA.js.map +0 -1
  148. package/dist/chunk-OVBZ2NBB.js.map +0 -1
  149. /package/dist/{chunk-MXYAZTDE.js.map → chunk-4FQCY75E.js.map} +0 -0
  150. /package/dist/{chunk-6QZUAJVF.js.map → chunk-GOJ45AG7.js.map} +0 -0
  151. /package/dist/{chunk-NGS5UKDW.js.map → chunk-ZNRTNR2Q.js.map} +0 -0
@@ -1,7 +1,6 @@
1
1
  import { type Temporal } from './shared/temporal.js';
2
2
  /**
3
- * Adds business days (Monday–Friday), skipping weekends. Holidays are not
4
- * considered.
3
+ * Adds business days (Monday–Friday), skipping weekends and any holidays you pass.
5
4
  *
6
5
  * Starting on a weekend, the first business day counted is the next Monday
7
6
  * (or the previous Friday for negative values). Adding 0 returns the input's
@@ -12,6 +11,8 @@ import { type Temporal } from './shared/temporal.js';
12
11
  *
13
12
  * @param input - An Instant (UTC), ZonedDateTime, or PlainDate
14
13
  * @param days - Whole business days to add (negative to subtract)
14
+ * @param holidays - Dates that are not business days. For Instant and ZonedDateTime
15
+ * inputs they are matched against the input's own date (UTC for Instant).
15
16
  * @returns PlainDate for a date input; otherwise ZonedDateTime
16
17
  * @throws RangeError if days is not an integer
17
18
  *
@@ -22,7 +23,16 @@ import { type Temporal } from './shared/temporal.js';
22
23
  * addBusinessDays(friday, 1); // 2025-01-27 (Monday)
23
24
  * addBusinessDays(friday, 5); // 2025-01-31 (Friday)
24
25
  * ```
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * // Skip holidays too
30
+ * const christmasEve = Temporal.PlainDate.from('2025-12-24');
31
+ * const holidays = [Temporal.PlainDate.from('2025-12-25'), Temporal.PlainDate.from('2025-12-26')];
32
+ *
33
+ * addBusinessDays(christmasEve, 1, holidays).toString(); // "2025-12-29"
34
+ * ```
25
35
  */
26
- export declare function addBusinessDays(input: Temporal.PlainDate, days: number): Temporal.PlainDate;
27
- export declare function addBusinessDays(input: Temporal.Instant | Temporal.ZonedDateTime, days: number): Temporal.ZonedDateTime;
36
+ export declare function addBusinessDays(input: Temporal.PlainDate, days: number, holidays?: readonly Temporal.PlainDate[]): Temporal.PlainDate;
37
+ export declare function addBusinessDays(input: Temporal.Instant | Temporal.ZonedDateTime, days: number, holidays?: readonly Temporal.PlainDate[]): Temporal.ZonedDateTime;
28
38
  //# sourceMappingURL=addBusinessDays.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"addBusinessDays.d.ts","sourceRoot":"","sources":["../src/addBusinessDays.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAe,MAAM,mBAAmB,CAAC;AAI/D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC,SAAS,CAAC;AAC7F,wBAAgB,eAAe,CAC7B,KAAK,EAAE,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAC,aAAa,EAChD,IAAI,EAAE,MAAM,GACX,QAAQ,CAAC,aAAa,CAAC"}
1
+ {"version":3,"file":"addBusinessDays.d.ts","sourceRoot":"","sources":["../src/addBusinessDays.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAe,MAAM,mBAAmB,CAAC;AAI/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,QAAQ,CAAC,SAAS,EACzB,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,SAAS,QAAQ,CAAC,SAAS,EAAE,GACvC,QAAQ,CAAC,SAAS,CAAC;AACtB,wBAAgB,eAAe,CAC7B,KAAK,EAAE,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAC,aAAa,EAChD,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,SAAS,QAAQ,CAAC,SAAS,EAAE,GACvC,QAAQ,CAAC,aAAa,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  addBusinessDays
3
- } from "./chunk-D3N7BT44.js";
4
- import "./chunk-K7CLBBBM.js";
3
+ } from "./chunk-2JXI3CAL.js";
4
+ import "./chunk-4YCEFGZA.js";
5
5
  import "./chunk-Q6QLOUXJ.js";
6
6
  import "./chunk-BSVOJYJ7.js";
7
7
  export {
@@ -0,0 +1,60 @@
1
+ import type { Temporal } from './shared/temporal.js';
2
+ import { type Timeline } from './shared/compare.js';
3
+ /**
4
+ * Returns true if two intervals share any time.
5
+ *
6
+ * By default an interval that ends exactly where the other starts does not
7
+ * overlap it, so back-to-back bookings are allowed. Pass `{ inclusive: true }`
8
+ * to count a shared endpoint, as for inclusive date ranges.
9
+ *
10
+ * Instants and ZonedDateTimes compare by the moment they represent. PlainDate
11
+ * intervals compare by date. Mixing PlainDate and timeline endpoints throws a
12
+ * TypeError; an interval whose start is after its end throws a RangeError.
13
+ *
14
+ * @param left - The first interval
15
+ * @param right - The second interval
16
+ * @param options - `inclusive`: count intervals that only touch as overlapping
17
+ * @returns true if the intervals overlap
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * const meeting = {
22
+ * start: Temporal.ZonedDateTime.from('2025-01-20T09:00:00+01:00[Europe/Madrid]'),
23
+ * end: Temporal.ZonedDateTime.from('2025-01-20T10:00:00+01:00[Europe/Madrid]')
24
+ * };
25
+ * const call = {
26
+ * start: Temporal.Instant.from('2025-01-20T08:30:00Z'), // 09:30 in Madrid
27
+ * end: Temporal.Instant.from('2025-01-20T09:30:00Z')
28
+ * };
29
+ *
30
+ * areIntervalsOverlapping(meeting, call); // true
31
+ * ```
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * const firstStay = { start: Temporal.PlainDate.from('2025-07-01'), end: Temporal.PlainDate.from('2025-07-04') };
36
+ * const nextStay = { start: Temporal.PlainDate.from('2025-07-04'), end: Temporal.PlainDate.from('2025-07-08') };
37
+ *
38
+ * areIntervalsOverlapping(firstStay, nextStay); // false
39
+ * areIntervalsOverlapping(firstStay, nextStay, { inclusive: true }); // true
40
+ * ```
41
+ */
42
+ export declare function areIntervalsOverlapping(left: {
43
+ start: Temporal.PlainDate;
44
+ end: Temporal.PlainDate;
45
+ }, right: {
46
+ start: Temporal.PlainDate;
47
+ end: Temporal.PlainDate;
48
+ }, options?: {
49
+ inclusive?: boolean;
50
+ }): boolean;
51
+ export declare function areIntervalsOverlapping(left: {
52
+ start: Timeline;
53
+ end: Timeline;
54
+ }, right: {
55
+ start: Timeline;
56
+ end: Timeline;
57
+ }, options?: {
58
+ inclusive?: boolean;
59
+ }): boolean;
60
+ //# sourceMappingURL=areIntervalsOverlapping.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"areIntervalsOverlapping.d.ts","sourceRoot":"","sources":["../src/areIntervalsOverlapping.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAW,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE;IAAE,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC;IAAC,GAAG,EAAE,QAAQ,CAAC,SAAS,CAAA;CAAE,EAC5D,KAAK,EAAE;IAAE,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC;IAAC,GAAG,EAAE,QAAQ,CAAC,SAAS,CAAA;CAAE,EAC7D,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAChC,OAAO,CAAC;AACX,wBAAgB,uBAAuB,CACrC,IAAI,EAAE;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,QAAQ,CAAA;CAAE,EACxC,KAAK,EAAE;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,QAAQ,CAAA;CAAE,EACzC,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAChC,OAAO,CAAC"}
@@ -0,0 +1,9 @@
1
+ import {
2
+ areIntervalsOverlapping
3
+ } from "./chunk-R6D3Y5NV.js";
4
+ import "./chunk-OMYVTYHI.js";
5
+ import "./chunk-BSVOJYJ7.js";
6
+ export {
7
+ areIntervalsOverlapping
8
+ };
9
+ //# sourceMappingURL=areIntervalsOverlapping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,22 @@
1
+ import {
2
+ addBusinessDaysSkipping
3
+ } from "./chunk-4YCEFGZA.js";
4
+ import {
5
+ normalizeTemporalInput
6
+ } from "./chunk-Q6QLOUXJ.js";
7
+ import {
8
+ isPlainDate
9
+ } from "./chunk-BSVOJYJ7.js";
10
+
11
+ // src/addBusinessDays.ts
12
+ function addBusinessDays(input, days, holidays = []) {
13
+ if (isPlainDate(input)) {
14
+ return addBusinessDaysSkipping(input, days, holidays);
15
+ }
16
+ return addBusinessDaysSkipping(normalizeTemporalInput(input), days, holidays);
17
+ }
18
+
19
+ export {
20
+ addBusinessDays
21
+ };
22
+ //# sourceMappingURL=chunk-2JXI3CAL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/addBusinessDays.ts"],"sourcesContent":["import { type Temporal, isPlainDate } from './shared/temporal';\nimport { normalizeTemporalInput } from './shared/normalizeTemporalInput';\nimport { addBusinessDaysSkipping } from './shared/businessDays';\n\n/**\n * Adds business days (Monday–Friday), skipping weekends and any holidays you pass.\n *\n * Starting on a weekend, the first business day counted is the next Monday\n * (or the previous Friday for negative values). Adding 0 returns the input's\n * date unchanged, even on a weekend.\n *\n * Instant inputs are converted to UTC. ZonedDateTime inputs keep their\n * timezone and time of day. PlainDate inputs stay dates.\n *\n * @param input - An Instant (UTC), ZonedDateTime, or PlainDate\n * @param days - Whole business days to add (negative to subtract)\n * @param holidays - Dates that are not business days. For Instant and ZonedDateTime\n * inputs they are matched against the input's own date (UTC for Instant).\n * @returns PlainDate for a date input; otherwise ZonedDateTime\n * @throws RangeError if days is not an integer\n *\n * @example\n * ```ts\n * const friday = Temporal.PlainDate.from('2025-01-24');\n *\n * addBusinessDays(friday, 1); // 2025-01-27 (Monday)\n * addBusinessDays(friday, 5); // 2025-01-31 (Friday)\n * ```\n *\n * @example\n * ```ts\n * // Skip holidays too\n * const christmasEve = Temporal.PlainDate.from('2025-12-24');\n * const holidays = [Temporal.PlainDate.from('2025-12-25'), Temporal.PlainDate.from('2025-12-26')];\n *\n * addBusinessDays(christmasEve, 1, holidays).toString(); // \"2025-12-29\"\n * ```\n */\nexport function addBusinessDays(\n input: Temporal.PlainDate,\n days: number,\n holidays?: readonly Temporal.PlainDate[]\n): Temporal.PlainDate;\nexport function addBusinessDays(\n input: Temporal.Instant | Temporal.ZonedDateTime,\n days: number,\n holidays?: readonly Temporal.PlainDate[]\n): Temporal.ZonedDateTime;\nexport function addBusinessDays(\n input: Temporal.Instant | Temporal.ZonedDateTime | Temporal.PlainDate,\n days: number,\n holidays: readonly Temporal.PlainDate[] = []\n): Temporal.ZonedDateTime | Temporal.PlainDate {\n if (isPlainDate(input)) {\n return addBusinessDaysSkipping(input, days, holidays);\n }\n return addBusinessDaysSkipping(normalizeTemporalInput(input), days, holidays);\n}\n"],"mappings":";;;;;;;;;;;AAgDO,SAAS,gBACd,OACA,MACA,WAA0C,CAAC,GACE;AAC7C,MAAI,YAAY,KAAK,GAAG;AACtB,WAAO,wBAAwB,OAAO,MAAM,QAAQ;AAAA,EACtD;AACA,SAAO,wBAAwB,uBAAuB,KAAK,GAAG,MAAM,QAAQ;AAC9E;","names":[]}
@@ -1,3 +1,6 @@
1
+ import {
2
+ consumeToken
3
+ } from "./chunk-HH2HTC44.js";
1
4
  import {
2
5
  formatPlainDate
3
6
  } from "./chunk-TWXUGWYX.js";
@@ -65,87 +68,6 @@ function format(input, formatStr, options = {}) {
65
68
  }
66
69
  return result;
67
70
  }
68
- function consumeToken(formatStr, start, char) {
69
- if (char === "M" && start + 1 < formatStr.length && formatStr[start + 1] === "o") {
70
- return "Mo";
71
- }
72
- if (char === "d" && start + 1 < formatStr.length && formatStr[start + 1] === "o") {
73
- return "do";
74
- }
75
- let end = start;
76
- while (end < formatStr.length && formatStr[end] === char) {
77
- end++;
78
- }
79
- const count = end - start;
80
- const validTokens = [
81
- "GGGGG",
82
- "GGGG",
83
- "GGG",
84
- "GG",
85
- "G",
86
- "yyyy",
87
- "yyy",
88
- "yy",
89
- "y",
90
- "QQQQQ",
91
- "QQQQ",
92
- "QQQ",
93
- "QQ",
94
- "Q",
95
- "MMMMM",
96
- "MMMM",
97
- "MMM",
98
- "MM",
99
- "M",
100
- "dd",
101
- "d",
102
- "EEEEEE",
103
- "EEEEE",
104
- "EEEE",
105
- "EEE",
106
- "EE",
107
- "E",
108
- "aaaaa",
109
- "aaaa",
110
- "aaa",
111
- "aa",
112
- "a",
113
- "HH",
114
- "H",
115
- "hh",
116
- "h",
117
- "mm",
118
- "m",
119
- "ss",
120
- "s",
121
- "SSS",
122
- "SS",
123
- "S",
124
- "XXXXX",
125
- "XXXX",
126
- "XXX",
127
- "XX",
128
- "X",
129
- "xxxxx",
130
- "xxxx",
131
- "xxx",
132
- "xx",
133
- "x",
134
- "zzzz",
135
- "zzz",
136
- "zz",
137
- "z",
138
- "T",
139
- "t"
140
- ];
141
- for (let len = Math.min(count, 6); len > 0; len--) {
142
- const candidate = char.repeat(len);
143
- if (validTokens.includes(candidate)) {
144
- return candidate;
145
- }
146
- }
147
- return null;
148
- }
149
71
  function formatToken(token, zonedDateTime, locale) {
150
72
  switch (token) {
151
73
  // Era
@@ -325,4 +247,4 @@ function isAm(period) {
325
247
  export {
326
248
  format
327
249
  };
328
- //# sourceMappingURL=chunk-BYPHFTFD.js.map
250
+ //# sourceMappingURL=chunk-2LT2XOAL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/format.ts"],"sourcesContent":["import { type Temporal, isInstant, isPlainDate } from './shared/temporal';\nimport { normalizeTemporalInput } from './shared/normalizeTemporalInput';\nimport type { Timezone } from './types';\nimport { formatPlainDate, type FormatPlainDateOptions } from './formatPlainDate';\nimport { consumeToken } from './shared/formatTokens';\n\nexport interface FormatOptions {\n locale?: string;\n timeZone?: Timezone;\n}\n\n/**\n * Format a Temporal.Instant, ZonedDateTime, or PlainDate using date-fns-like format tokens.\n * Uses Intl.DateTimeFormat for localized parts. PlainDate inputs delegate to\n * formatPlainDate and accept locale options only; no time or timezone is invented.\n *\n * @param input - A Temporal.Instant, Temporal.ZonedDateTime, or Temporal.PlainDate to format\n * @param formatStr - Format string using date-fns tokens (e.g., \"yyyy-MM-dd HH:mm:ss\")\n * @param options - Optional configuration for locale and timezone\n * @returns Formatted date string\n *\n * @example\n * ```typescript\n * const zoned = Temporal.ZonedDateTime.from(\"2025-01-20T15:00:00-05:00[America/New_York]\");\n *\n * format(zoned, \"yyyy-MM-dd\"); // \"2025-01-20\"\n * format(zoned, \"MMMM d, yyyy\"); // \"January 20, 2025\"\n * format(zoned, \"h:mm a\"); // \"3:00 PM\"\n * format(zoned, \"EEEE, MMMM do, yyyy 'at' h:mm a\"); // \"Monday, January 20th, 2025 at 3:00 PM\"\n *\n * // With locale\n * format(zoned, \"MMMM d, yyyy\", { locale: \"es-ES\" }); // \"enero 20, 2025\"\n * ```\n */\nexport function format(\n input: Temporal.PlainDate,\n formatStr: string,\n options?: FormatPlainDateOptions & { timeZone?: never }\n): string;\nexport function format(\n input: Temporal.Instant | Temporal.ZonedDateTime,\n formatStr: string,\n options?: FormatOptions\n): string;\nexport function format(\n input: Temporal.Instant | Temporal.ZonedDateTime | Temporal.PlainDate,\n formatStr: string,\n options: FormatOptions = {}\n): string {\n if (isPlainDate(input)) {\n if (options.timeZone !== undefined) {\n throw new TypeError('PlainDate formatting does not accept a timezone');\n }\n return formatPlainDate(input, formatStr, options);\n }\n const { locale = 'en-US', timeZone } = options;\n\n // Convert to ZonedDateTime, applying custom timezone if provided\n let zonedDateTime: Temporal.ZonedDateTime;\n if (timeZone) {\n // If custom timezone specified, convert via Instant\n const instant = isInstant(input) ? input : input.toInstant();\n zonedDateTime = instant.toZonedDateTimeISO(timeZone);\n } else {\n // No custom timezone: normalize to ZonedDateTime (Instant -> UTC, ZonedDateTime -> keep as-is)\n zonedDateTime = normalizeTemporalInput(input);\n }\n\n let result = '';\n let i = 0;\n const len = formatStr.length;\n\n while (i < len) {\n const char = formatStr[i];\n if (!char) break;\n\n // Handle escaped text\n if (char === \"'\") {\n // Check for double single quote (not inside a string, just '')\n if (i + 1 < len && formatStr[i + 1] === \"'\") {\n result += \"'\";\n i += 2;\n continue;\n }\n // Find closing quote, handling '' inside the string\n i++;\n while (i < len) {\n if (formatStr[i] === \"'\") {\n // Check if it's a doubled quote ''\n if (i + 1 < len && formatStr[i + 1] === \"'\") {\n result += \"'\";\n i += 2;\n } else {\n // End of quoted string\n i++;\n break;\n }\n } else {\n result += formatStr[i];\n i++;\n }\n }\n continue;\n }\n\n // Check for tokens by looking ahead\n const token = consumeToken(formatStr, i, char);\n if (token !== null) {\n result += formatToken(token, zonedDateTime, locale);\n i += token.length;\n } else {\n result += char;\n i++;\n }\n }\n\n return result;\n}\n\nfunction formatToken(token: string, zonedDateTime: Temporal.ZonedDateTime, locale: string): string {\n switch (token) {\n // Era\n case 'GGGGG':\n return formatPart(zonedDateTime, 'era', 'narrow', locale);\n case 'GGGG':\n return formatPart(zonedDateTime, 'era', 'long', locale);\n case 'GGG':\n case 'GG':\n case 'G':\n return formatPart(zonedDateTime, 'era', 'short', locale);\n\n // Year\n case 'yyyy':\n return zonedDateTime.year.toString().padStart(4, '0');\n case 'yyy':\n return zonedDateTime.year.toString().padStart(3, '0');\n case 'yy':\n return (zonedDateTime.year % 100).toString().padStart(2, '0');\n case 'y':\n return zonedDateTime.year.toString();\n\n // Quarter\n case 'QQQQQ':\n return Math.ceil(zonedDateTime.month / 3).toString();\n case 'QQQQ': {\n const quarter = Math.ceil(zonedDateTime.month / 3);\n return `${quarter}${getOrdinalSuffix(quarter)} quarter`;\n }\n case 'QQQ':\n return `Q${Math.ceil(zonedDateTime.month / 3)}`;\n case 'QQ':\n return Math.ceil(zonedDateTime.month / 3)\n .toString()\n .padStart(2, '0');\n case 'Q':\n return Math.ceil(zonedDateTime.month / 3).toString();\n\n // Month\n case 'MMMMM':\n return formatPart(zonedDateTime, 'month', 'narrow', locale);\n case 'MMMM':\n return formatPart(zonedDateTime, 'month', 'long', locale);\n case 'MMM':\n return formatPart(zonedDateTime, 'month', 'short', locale);\n case 'MM':\n return zonedDateTime.month.toString().padStart(2, '0');\n case 'Mo':\n return `${zonedDateTime.month}${getOrdinalSuffix(zonedDateTime.month)}`;\n case 'M':\n return zonedDateTime.month.toString();\n\n // Day of month\n case 'do':\n return `${zonedDateTime.day}${getOrdinalSuffix(zonedDateTime.day)}`;\n case 'dd':\n return zonedDateTime.day.toString().padStart(2, '0');\n case 'd':\n return zonedDateTime.day.toString();\n\n // Day of week\n case 'EEEEEE':\n return formatPart(zonedDateTime, 'weekday', 'short', locale).slice(0, 2);\n case 'EEEEE':\n return formatPart(zonedDateTime, 'weekday', 'narrow', locale);\n case 'EEEE':\n return formatPart(zonedDateTime, 'weekday', 'long', locale);\n case 'EEE':\n case 'EE':\n case 'E':\n return formatPart(zonedDateTime, 'weekday', 'short', locale);\n\n // AM/PM (locale-aware; English widths applied only for ASCII AM/PM)\n case 'aaaaa': {\n const period = getDayPeriod(zonedDateTime, locale);\n if (isAsciiAmPm(period)) return isAm(period) ? 'a' : 'p';\n return period.charAt(0).toLowerCase();\n }\n case 'aaaa': {\n const period = getDayPeriod(zonedDateTime, locale);\n if (isAsciiAmPm(period)) return isAm(period) ? 'a.m.' : 'p.m.';\n return period;\n }\n case 'aaa':\n return getDayPeriod(zonedDateTime, locale).toLowerCase();\n case 'aa':\n case 'a':\n return getDayPeriod(zonedDateTime, locale);\n\n // Hour [0-23]\n case 'HH':\n return zonedDateTime.hour.toString().padStart(2, '0');\n case 'H':\n return zonedDateTime.hour.toString();\n\n // Hour [1-12]\n case 'hh': {\n const hour12 = zonedDateTime.hour % 12 || 12;\n return hour12.toString().padStart(2, '0');\n }\n case 'h': {\n const hour12 = zonedDateTime.hour % 12 || 12;\n return hour12.toString();\n }\n\n // Minute\n case 'mm':\n return zonedDateTime.minute.toString().padStart(2, '0');\n case 'm':\n return zonedDateTime.minute.toString();\n\n // Second\n case 'ss':\n return zonedDateTime.second.toString().padStart(2, '0');\n case 's':\n return zonedDateTime.second.toString();\n\n // Fractional seconds\n case 'SSS':\n return zonedDateTime.millisecond.toString().padStart(3, '0');\n case 'SS':\n return Math.floor(zonedDateTime.millisecond / 10)\n .toString()\n .padStart(2, '0');\n case 'S':\n return Math.floor(zonedDateTime.millisecond / 100).toString();\n\n // Timezone\n case 'XXXXX':\n case 'XXXX':\n case 'XXX':\n case 'XX':\n case 'X':\n case 'xxxxx':\n case 'xxxx':\n case 'xxx':\n case 'xx':\n case 'x':\n return formatTimezoneOffset(zonedDateTime, token);\n case 'zzzz':\n return formatPart(zonedDateTime, 'timeZoneName', 'long', locale);\n case 'zzz':\n case 'zz':\n case 'z':\n return formatPart(zonedDateTime, 'timeZoneName', 'short', locale);\n\n // Timestamps\n case 'T':\n return zonedDateTime.epochMilliseconds.toString();\n case 't':\n return Math.floor(zonedDateTime.epochMilliseconds / 1000).toString();\n\n default:\n return token;\n }\n}\n\nfunction formatPart(\n zonedDateTime: Temporal.ZonedDateTime,\n part: 'era' | 'year' | 'month' | 'weekday' | 'day' | 'hour' | 'minute' | 'second' | 'timeZoneName',\n style: 'narrow' | 'short' | 'long' | 'numeric' | '2-digit',\n locale: string\n): string {\n const options: Intl.DateTimeFormatOptions = {\n [part]: style,\n timeZone: zonedDateTime.timeZoneId,\n calendar: zonedDateTime.calendarId === 'iso8601' ? undefined : zonedDateTime.calendarId,\n };\n return new Intl.DateTimeFormat(locale, options)\n .formatToParts(zonedDateTime.epochMilliseconds)\n .find(value => value.type === part)?.value ?? '';\n}\n\nfunction getOrdinalSuffix(num: number): string {\n const j = num % 10;\n const k = num % 100;\n if (j === 1 && k !== 11) return 'st';\n if (j === 2 && k !== 12) return 'nd';\n if (j === 3 && k !== 13) return 'rd';\n return 'th';\n}\n\nfunction formatTimezoneOffset(zonedDateTime: Temporal.ZonedDateTime, token: string): string {\n if (token[0] === 'X' && zonedDateTime.offsetNanoseconds === 0) return 'Z';\n\n // Temporal supplies integer HH:mm[:ss] fields. Widths 1–3 omit seconds;\n // widths 4–5 retain them when present, as specified by Unicode date tokens.\n const offset = token.length >= 4 ? zonedDateTime.offset : zonedDateTime.offset.slice(0, 6);\n if (token.length === 1 && offset.endsWith(':00')) return offset.slice(0, 3);\n return token.length === 3 || token.length === 5 ? offset : offset.replaceAll(':', '');\n}\n\n/**\n * Locale-correct day period (AM/PM equivalent) via Intl.formatToParts.\n * Returns the locale's own value, e.g. \"AM\"/\"PM\" (en), \"p. m.\" (es), \"午後\" (ja).\n */\nfunction getDayPeriod(zonedDateTime: Temporal.ZonedDateTime, locale: string): string {\n const parts = new Intl.DateTimeFormat(locale, {\n hour: 'numeric',\n hour12: true,\n timeZone: zonedDateTime.timeZoneId,\n }).formatToParts(zonedDateTime.epochMilliseconds);\n return parts.find((p) => p.type === 'dayPeriod')?.value ?? '';\n}\n\n/** True when the day-period is recognizably ASCII AM/PM (so English widths apply). */\nfunction isAsciiAmPm(period: string): boolean {\n const normalized = period.toUpperCase().replace(/[.\\s]/g, '');\n return normalized === 'AM' || normalized === 'PM';\n}\n\n/** True for the AM half (only meaningful when isAsciiAmPm is true). */\nfunction isAm(period: string): boolean {\n return period.toUpperCase().replace(/[.\\s]/g, '').startsWith('A');\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,247 @@
1
+ import {
2
+ consumeToken
3
+ } from "./chunk-HH2HTC44.js";
4
+ import {
5
+ Temporal
6
+ } from "./chunk-BSVOJYJ7.js";
7
+
8
+ // src/parse.ts
9
+ function parse(text, pattern, options = {}) {
10
+ const { locale = "en-US", timeZone } = options;
11
+ const fields = readFields(text, pattern, locale);
12
+ const fail = (reason) => new RangeError(`Cannot parse "${text}" with pattern "${pattern}": ${reason}`);
13
+ if (fields.year === void 0 || fields.month === void 0 || fields.day === void 0) {
14
+ throw fail("the pattern needs a year, month, and day");
15
+ }
16
+ const date = Temporal.PlainDate.from(
17
+ { year: fields.year, month: fields.month, day: fields.day },
18
+ { overflow: "reject" }
19
+ );
20
+ if (fields.dayOfWeek !== void 0 && fields.dayOfWeek !== date.dayOfWeek) {
21
+ throw fail(`${date} is not that day of the week`);
22
+ }
23
+ const hasTime = fields.hour !== void 0 || fields.hour12 !== void 0 || fields.minute !== void 0 || fields.second !== void 0 || fields.millisecond !== void 0;
24
+ if (timeZone === void 0) {
25
+ if (hasTime || fields.offset !== void 0) {
26
+ throw new TypeError("Patterns with time or offset fields need a timeZone");
27
+ }
28
+ return date;
29
+ }
30
+ if (!hasTime && fields.offset === void 0) {
31
+ return date.toZonedDateTime(timeZone);
32
+ }
33
+ if (fields.hour12 !== void 0) {
34
+ if (fields.pm === void 0) throw fail("12-hour times (h) need AM/PM (a)");
35
+ if (fields.hour12 < 1 || fields.hour12 > 12)
36
+ throw fail(`${fields.hour12} is not a 12-hour hour`);
37
+ }
38
+ const hour = fields.hour ?? (fields.hour12 === void 0 ? 0 : fields.hour12 % 12 + (fields.pm ? 12 : 0));
39
+ const dateTime = Temporal.PlainDateTime.from(
40
+ {
41
+ year: date.year,
42
+ month: date.month,
43
+ day: date.day,
44
+ hour,
45
+ minute: fields.minute ?? 0,
46
+ second: fields.second ?? 0,
47
+ millisecond: fields.millisecond ?? 0
48
+ },
49
+ { overflow: "reject" }
50
+ );
51
+ if (fields.offset !== void 0) {
52
+ return Temporal.Instant.from(`${dateTime}${fields.offset}`).toZonedDateTimeISO(timeZone);
53
+ }
54
+ return dateTime.toZonedDateTime(timeZone);
55
+ }
56
+ function readFields(text, pattern, locale) {
57
+ const fields = {};
58
+ let position = 0;
59
+ const fail = (reason) => new RangeError(`Cannot parse "${text}" with pattern "${pattern}": ${reason}`);
60
+ const literal = (expected) => {
61
+ if (!text.startsWith(expected, position)) {
62
+ throw fail(`expected "${expected}" at position ${position}`);
63
+ }
64
+ position += expected.length;
65
+ };
66
+ const digits = (min, max) => {
67
+ const match = text.slice(position).match(new RegExp(`^\\d{${min},${max}}`));
68
+ if (!match)
69
+ throw fail(`expected ${min === max ? min : `${min}\u2013${max}`} digits at position ${position}`);
70
+ position += match[0].length;
71
+ return match[0];
72
+ };
73
+ const name = (candidates) => {
74
+ const rest = text.slice(position).toLocaleLowerCase(locale);
75
+ let best = -1;
76
+ let length = 0;
77
+ candidates.forEach((candidate, index) => {
78
+ const lower = candidate.toLocaleLowerCase(locale);
79
+ if (lower.length > length && rest.startsWith(lower)) {
80
+ best = index;
81
+ length = lower.length;
82
+ }
83
+ });
84
+ if (best === -1) throw fail(`expected one of ${candidates.join(", ")} at position ${position}`);
85
+ position += length;
86
+ return best;
87
+ };
88
+ for (let i = 0; i < pattern.length; ) {
89
+ const char = pattern[i];
90
+ if (char === "'") {
91
+ if (pattern[i + 1] === "'") {
92
+ literal("'");
93
+ i += 2;
94
+ continue;
95
+ }
96
+ let quoted = "";
97
+ for (i++; i < pattern.length; i++) {
98
+ if (pattern[i] !== "'") quoted += pattern[i];
99
+ else if (pattern[i + 1] === "'") quoted += "'", i++;
100
+ else break;
101
+ }
102
+ literal(quoted);
103
+ i++;
104
+ continue;
105
+ }
106
+ const token = consumeToken(pattern, i, char);
107
+ if (token === null) {
108
+ literal(char);
109
+ i++;
110
+ continue;
111
+ }
112
+ i += token.length;
113
+ switch (token) {
114
+ case "yyyy":
115
+ fields.year = Number(digits(4, 4));
116
+ break;
117
+ case "y":
118
+ fields.year = Number(digits(1, 6));
119
+ break;
120
+ case "MMMM":
121
+ case "MMM":
122
+ fields.month = name(monthNames(locale, token === "MMMM" ? "long" : "short")) + 1;
123
+ break;
124
+ case "MM":
125
+ fields.month = Number(digits(2, 2));
126
+ break;
127
+ case "M":
128
+ fields.month = Number(digits(1, 2));
129
+ break;
130
+ case "dd":
131
+ fields.day = Number(digits(2, 2));
132
+ break;
133
+ case "d":
134
+ fields.day = Number(digits(1, 2));
135
+ break;
136
+ case "EEEE":
137
+ case "EEE":
138
+ case "EE":
139
+ case "E":
140
+ fields.dayOfWeek = name(weekdayNames(locale, token === "EEEE" ? "long" : "short")) + 1;
141
+ break;
142
+ case "HH":
143
+ fields.hour = Number(digits(2, 2));
144
+ break;
145
+ case "H":
146
+ fields.hour = Number(digits(1, 2));
147
+ break;
148
+ case "hh":
149
+ fields.hour12 = Number(digits(2, 2));
150
+ break;
151
+ case "h":
152
+ fields.hour12 = Number(digits(1, 2));
153
+ break;
154
+ case "aaaa":
155
+ case "aaa":
156
+ case "aa":
157
+ case "a": {
158
+ const [am, pm] = dayPeriods(locale);
159
+ const candidates = [am, pm];
160
+ if (isAsciiAmPm(am) && isAsciiAmPm(pm)) candidates.push("a.m.", "p.m.");
161
+ fields.pm = name(candidates) % 2 === 1;
162
+ break;
163
+ }
164
+ case "mm":
165
+ fields.minute = Number(digits(2, 2));
166
+ break;
167
+ case "m":
168
+ fields.minute = Number(digits(1, 2));
169
+ break;
170
+ case "ss":
171
+ fields.second = Number(digits(2, 2));
172
+ break;
173
+ case "s":
174
+ fields.second = Number(digits(1, 2));
175
+ break;
176
+ case "SSS":
177
+ case "SS":
178
+ case "S":
179
+ fields.millisecond = Number(digits(token.length, token.length).padEnd(3, "0"));
180
+ break;
181
+ default:
182
+ if (/^[Xx]+$/.test(token)) {
183
+ const match = text.slice(position).match(token[0] === "X" ? /^(Z|[+-]\d{2}(:?\d{2}){0,2})/ : /^[+-]\d{2}(:?\d{2}){0,2}/);
184
+ if (!match) throw fail(`expected a UTC offset at position ${position}`);
185
+ position += match[0].length;
186
+ fields.offset = match[0] === "Z" ? "+00:00" : normalizeOffset(match[0]);
187
+ break;
188
+ }
189
+ throw new RangeError(
190
+ token === "yy" ? "parse does not read two-digit years (yy); the century would be a guess" : token === "T" || token === "t" ? "parse does not read timestamps (T, t); use toInstant" : `parse does not support the "${token}" token`
191
+ );
192
+ }
193
+ }
194
+ if (position !== text.length) {
195
+ throw fail(`unexpected "${text.slice(position)}" at position ${position}`);
196
+ }
197
+ return fields;
198
+ }
199
+ function normalizeOffset(offset) {
200
+ const numbers = offset.slice(1).replaceAll(":", "");
201
+ const parts = numbers.match(/\d{2}/g);
202
+ return `${offset[0]}${parts.length === 1 ? `${parts[0]}:00` : parts.join(":")}`;
203
+ }
204
+ function intlPart(locale, options, type, date) {
205
+ const epochMilliseconds = date.toZonedDateTime("UTC").epochMilliseconds;
206
+ return new Intl.DateTimeFormat(locale, { ...options, timeZone: "UTC" }).formatToParts(epochMilliseconds).find((part) => part.type === type)?.value ?? "";
207
+ }
208
+ function monthNames(locale, style) {
209
+ return Array.from(
210
+ { length: 12 },
211
+ (_, index) => intlPart(
212
+ locale,
213
+ { month: style },
214
+ "month",
215
+ Temporal.PlainDateTime.from({ year: 2e3, month: index + 1, day: 15 })
216
+ )
217
+ );
218
+ }
219
+ function weekdayNames(locale, style) {
220
+ return Array.from(
221
+ { length: 7 },
222
+ (_, index) => intlPart(
223
+ locale,
224
+ { weekday: style },
225
+ "weekday",
226
+ Temporal.PlainDateTime.from({ year: 2e3, month: 1, day: 3 + index })
227
+ )
228
+ );
229
+ }
230
+ function dayPeriods(locale) {
231
+ const at = (hour) => intlPart(
232
+ locale,
233
+ { hour: "numeric", hour12: true },
234
+ "dayPeriod",
235
+ Temporal.PlainDateTime.from({ year: 2e3, month: 1, day: 3, hour })
236
+ );
237
+ return [at(9), at(15)];
238
+ }
239
+ function isAsciiAmPm(period) {
240
+ const normalized = period.toUpperCase().replace(/[.\s]/g, "");
241
+ return normalized === "AM" || normalized === "PM";
242
+ }
243
+
244
+ export {
245
+ parse
246
+ };
247
+ //# sourceMappingURL=chunk-3OOGJRXH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/parse.ts"],"sourcesContent":["import { Temporal } from './shared/temporal';\nimport { consumeToken } from './shared/formatTokens';\nimport type { Timezone } from './types';\n\nexport interface ParseOptions {\n /** Locale for month, weekday, and AM/PM names. @default 'en-US' */\n locale?: string;\n /** Timezone the parsed wall-clock time belongs to. Required when the pattern has time fields. */\n timeZone?: Timezone;\n}\n\ninterface Fields {\n year?: number;\n month?: number;\n day?: number;\n dayOfWeek?: number;\n hour?: number;\n hour12?: number;\n pm?: boolean;\n minute?: number;\n second?: number;\n millisecond?: number;\n offset?: string;\n}\n\n/**\n * Reads a date, or a date and time, written in a known pattern. The pattern uses\n * the same tokens as `format`, so text that `format` writes with a supported\n * pattern reads back to the same fields.\n *\n * Without a timeZone the result is a PlainDate, and the pattern may only hold\n * date fields. With a timeZone the result is a ZonedDateTime in that timezone:\n * an offset in the text (`XXX`) fixes the moment, otherwise the wall-clock time\n * is read in the timezone, and a time skipped by a DST change moves forward as\n * in Temporal. A pattern without time fields gives the start of that day.\n *\n * Supported tokens: `yyyy` `y` `MMMM` `MMM` `MM` `M` `dd` `d` `EEEE` `EEE` `HH`\n * `H` `hh` `h` `a` `mm` `m` `ss` `s` `SSS` `SS` `S` `X…XXXXX` `x…xxxxx`. Text in\n * single quotes and any other character must match exactly. Two-digit years\n * (`yy`) are rejected because the century is a guess.\n *\n * @param text - The text to read\n * @param pattern - The pattern the text is written in, such as `dd/MM/yyyy`\n * @param options - `timeZone` for patterns with a time; `locale` for names (default 'en-US')\n * @returns PlainDate without a timeZone; ZonedDateTime with one\n * @throws RangeError if the text does not match the pattern or names an impossible date\n * @throws TypeError if the pattern has time fields but no timeZone is given\n *\n * @example\n * ```ts\n * parse('20/01/2025', 'dd/MM/yyyy').toString(); // \"2025-01-20\"\n * parse('January 20, 2025', 'MMMM d, yyyy').toString(); // \"2025-01-20\"\n * ```\n *\n * @example\n * ```ts\n * parse('01/20/2025 3:45 PM', 'MM/dd/yyyy h:mm a', { timeZone: 'America/New_York' }).toString();\n * // \"2025-01-20T15:45:00-05:00[America/New_York]\"\n * ```\n *\n * @example\n * ```ts\n * parse('20 enero 2025', 'd MMMM yyyy', { locale: 'es' }).toString(); // \"2025-01-20\"\n * ```\n */\nexport function parse(\n text: string,\n pattern: string,\n options: { locale?: string; timeZone: Timezone }\n): Temporal.ZonedDateTime;\nexport function parse(\n text: string,\n pattern: string,\n options?: { locale?: string; timeZone?: undefined }\n): Temporal.PlainDate;\nexport function parse(\n text: string,\n pattern: string,\n options: ParseOptions = {}\n): Temporal.ZonedDateTime | Temporal.PlainDate {\n const { locale = 'en-US', timeZone } = options;\n const fields = readFields(text, pattern, locale);\n const fail = (reason: string) =>\n new RangeError(`Cannot parse \"${text}\" with pattern \"${pattern}\": ${reason}`);\n\n if (fields.year === undefined || fields.month === undefined || fields.day === undefined) {\n throw fail('the pattern needs a year, month, and day');\n }\n const date = Temporal.PlainDate.from(\n { year: fields.year, month: fields.month, day: fields.day },\n { overflow: 'reject' }\n );\n if (fields.dayOfWeek !== undefined && fields.dayOfWeek !== date.dayOfWeek) {\n throw fail(`${date} is not that day of the week`);\n }\n\n const hasTime =\n fields.hour !== undefined ||\n fields.hour12 !== undefined ||\n fields.minute !== undefined ||\n fields.second !== undefined ||\n fields.millisecond !== undefined;\n if (timeZone === undefined) {\n if (hasTime || fields.offset !== undefined) {\n throw new TypeError('Patterns with time or offset fields need a timeZone');\n }\n return date;\n }\n if (!hasTime && fields.offset === undefined) {\n return date.toZonedDateTime(timeZone);\n }\n\n if (fields.hour12 !== undefined) {\n if (fields.pm === undefined) throw fail('12-hour times (h) need AM/PM (a)');\n if (fields.hour12 < 1 || fields.hour12 > 12)\n throw fail(`${fields.hour12} is not a 12-hour hour`);\n }\n const hour =\n fields.hour ?? (fields.hour12 === undefined ? 0 : (fields.hour12 % 12) + (fields.pm ? 12 : 0));\n const dateTime = Temporal.PlainDateTime.from(\n {\n year: date.year,\n month: date.month,\n day: date.day,\n hour,\n minute: fields.minute ?? 0,\n second: fields.second ?? 0,\n millisecond: fields.millisecond ?? 0\n },\n { overflow: 'reject' }\n );\n if (fields.offset !== undefined) {\n return Temporal.Instant.from(`${dateTime}${fields.offset}`).toZonedDateTimeISO(timeZone);\n }\n return dateTime.toZonedDateTime(timeZone);\n}\n\nfunction readFields(text: string, pattern: string, locale: string): Fields {\n const fields: Fields = {};\n let position = 0;\n const fail = (reason: string) =>\n new RangeError(`Cannot parse \"${text}\" with pattern \"${pattern}\": ${reason}`);\n\n const literal = (expected: string) => {\n if (!text.startsWith(expected, position)) {\n throw fail(`expected \"${expected}\" at position ${position}`);\n }\n position += expected.length;\n };\n\n const digits = (min: number, max: number) => {\n const match = text.slice(position).match(new RegExp(`^\\\\d{${min},${max}}`));\n if (!match)\n throw fail(`expected ${min === max ? min : `${min}–${max}`} digits at position ${position}`);\n position += match[0].length;\n return match[0];\n };\n\n const name = (candidates: readonly string[]) => {\n const rest = text.slice(position).toLocaleLowerCase(locale);\n let best = -1;\n let length = 0;\n candidates.forEach((candidate, index) => {\n const lower = candidate.toLocaleLowerCase(locale);\n if (lower.length > length && rest.startsWith(lower)) {\n best = index;\n length = lower.length;\n }\n });\n if (best === -1) throw fail(`expected one of ${candidates.join(', ')} at position ${position}`);\n position += length;\n return best;\n };\n\n for (let i = 0; i < pattern.length;) {\n const char = pattern[i]!;\n\n if (char === \"'\") {\n // '' is a literal quote; 'text' is literal text with '' for a quote inside.\n if (pattern[i + 1] === \"'\") {\n literal(\"'\");\n i += 2;\n continue;\n }\n let quoted = '';\n for (i++; i < pattern.length; i++) {\n if (pattern[i] !== \"'\") quoted += pattern[i];\n else if (pattern[i + 1] === \"'\") ((quoted += \"'\"), i++);\n else break;\n }\n literal(quoted);\n i++;\n continue;\n }\n\n const token = consumeToken(pattern, i, char);\n if (token === null) {\n literal(char);\n i++;\n continue;\n }\n i += token.length;\n\n switch (token) {\n case 'yyyy':\n fields.year = Number(digits(4, 4));\n break;\n case 'y':\n fields.year = Number(digits(1, 6));\n break;\n case 'MMMM':\n case 'MMM':\n fields.month = name(monthNames(locale, token === 'MMMM' ? 'long' : 'short')) + 1;\n break;\n case 'MM':\n fields.month = Number(digits(2, 2));\n break;\n case 'M':\n fields.month = Number(digits(1, 2));\n break;\n case 'dd':\n fields.day = Number(digits(2, 2));\n break;\n case 'd':\n fields.day = Number(digits(1, 2));\n break;\n case 'EEEE':\n case 'EEE':\n case 'EE':\n case 'E':\n fields.dayOfWeek = name(weekdayNames(locale, token === 'EEEE' ? 'long' : 'short')) + 1;\n break;\n case 'HH':\n fields.hour = Number(digits(2, 2));\n break;\n case 'H':\n fields.hour = Number(digits(1, 2));\n break;\n case 'hh':\n fields.hour12 = Number(digits(2, 2));\n break;\n case 'h':\n fields.hour12 = Number(digits(1, 2));\n break;\n case 'aaaa':\n case 'aaa':\n case 'aa':\n case 'a': {\n const [am, pm] = dayPeriods(locale);\n const candidates = [am, pm];\n if (isAsciiAmPm(am) && isAsciiAmPm(pm)) candidates.push('a.m.', 'p.m.');\n fields.pm = name(candidates) % 2 === 1;\n break;\n }\n case 'mm':\n fields.minute = Number(digits(2, 2));\n break;\n case 'm':\n fields.minute = Number(digits(1, 2));\n break;\n case 'ss':\n fields.second = Number(digits(2, 2));\n break;\n case 's':\n fields.second = Number(digits(1, 2));\n break;\n case 'SSS':\n case 'SS':\n case 'S':\n fields.millisecond = Number(digits(token.length, token.length).padEnd(3, '0'));\n break;\n default:\n if (/^[Xx]+$/.test(token)) {\n const match = text\n .slice(position)\n .match(token[0] === 'X' ? /^(Z|[+-]\\d{2}(:?\\d{2}){0,2})/ : /^[+-]\\d{2}(:?\\d{2}){0,2}/);\n if (!match) throw fail(`expected a UTC offset at position ${position}`);\n position += match[0].length;\n fields.offset = match[0] === 'Z' ? '+00:00' : normalizeOffset(match[0]);\n break;\n }\n throw new RangeError(\n token === 'yy'\n ? 'parse does not read two-digit years (yy); the century would be a guess'\n : token === 'T' || token === 't'\n ? 'parse does not read timestamps (T, t); use toInstant'\n : `parse does not support the \"${token}\" token`\n );\n }\n }\n\n if (position !== text.length) {\n throw fail(`unexpected \"${text.slice(position)}\" at position ${position}`);\n }\n return fields;\n}\n\n// \"+0530\" and \"+05:30\" both become \"+05:30\", which Temporal reads.\nfunction normalizeOffset(offset: string): string {\n const numbers = offset.slice(1).replaceAll(':', '');\n const parts = numbers.match(/\\d{2}/g)!;\n return `${offset[0]}${parts.length === 1 ? `${parts[0]}:00` : parts.join(':')}`;\n}\n\n// Names come from Intl exactly as format writes them, so what format writes, parse reads.\nfunction intlPart(\n locale: string,\n options: Intl.DateTimeFormatOptions,\n type: Intl.DateTimeFormatPartTypes,\n date: Temporal.PlainDateTime\n): string {\n const epochMilliseconds = date.toZonedDateTime('UTC').epochMilliseconds;\n return (\n new Intl.DateTimeFormat(locale, { ...options, timeZone: 'UTC' })\n .formatToParts(epochMilliseconds)\n .find((part) => part.type === type)?.value ?? ''\n );\n}\n\nfunction monthNames(locale: string, style: 'long' | 'short'): string[] {\n return Array.from({ length: 12 }, (_, index) =>\n intlPart(\n locale,\n { month: style },\n 'month',\n Temporal.PlainDateTime.from({ year: 2000, month: index + 1, day: 15 })\n )\n );\n}\n\nfunction weekdayNames(locale: string, style: 'long' | 'short'): string[] {\n // 3 January 2000 was a Monday.\n return Array.from({ length: 7 }, (_, index) =>\n intlPart(\n locale,\n { weekday: style },\n 'weekday',\n Temporal.PlainDateTime.from({ year: 2000, month: 1, day: 3 + index })\n )\n );\n}\n\nfunction dayPeriods(locale: string): [am: string, pm: string] {\n const at = (hour: number) =>\n intlPart(\n locale,\n { hour: 'numeric', hour12: true },\n 'dayPeriod',\n Temporal.PlainDateTime.from({ year: 2000, month: 1, day: 3, hour })\n );\n return [at(9), at(15)];\n}\n\nfunction isAsciiAmPm(period: string): boolean {\n const normalized = period.toUpperCase().replace(/[.\\s]/g, '');\n return normalized === 'AM' || normalized === 'PM';\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,16 @@
1
+ import {
2
+ addBusinessDays
3
+ } from "./chunk-2JXI3CAL.js";
4
+ import {
5
+ isPlainDate
6
+ } from "./chunk-BSVOJYJ7.js";
7
+
8
+ // src/subBusinessDays.ts
9
+ function subBusinessDays(input, days, holidays) {
10
+ return isPlainDate(input) ? addBusinessDays(input, -days, holidays) : addBusinessDays(input, -days, holidays);
11
+ }
12
+
13
+ export {
14
+ subBusinessDays
15
+ };
16
+ //# sourceMappingURL=chunk-42IFQS4W.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/subBusinessDays.ts"],"sourcesContent":["import { type Temporal, isPlainDate } from './shared/temporal';\nimport { addBusinessDays } from './addBusinessDays';\n\n/**\n * Subtracts business days (Monday–Friday), skipping weekends and any holidays\n * you pass. Equivalent to `addBusinessDays(input, -days, holidays)`.\n *\n * Instant inputs are converted to UTC. ZonedDateTime inputs keep their\n * timezone and time of day. PlainDate inputs stay dates.\n *\n * @param input - An Instant (UTC), ZonedDateTime, or PlainDate\n * @param days - Whole business days to subtract (negative to add)\n * @param holidays - Dates that are not business days. For Instant and ZonedDateTime\n * inputs they are matched against the input's own date (UTC for Instant).\n * @returns PlainDate for a date input; otherwise ZonedDateTime\n * @throws RangeError if days is not an integer\n *\n * @example\n * ```ts\n * const monday = Temporal.PlainDate.from('2025-01-27');\n *\n * subBusinessDays(monday, 1); // 2025-01-24 (Friday)\n * ```\n */\nexport function subBusinessDays(\n input: Temporal.PlainDate,\n days: number,\n holidays?: readonly Temporal.PlainDate[]\n): Temporal.PlainDate;\nexport function subBusinessDays(\n input: Temporal.Instant | Temporal.ZonedDateTime,\n days: number,\n holidays?: readonly Temporal.PlainDate[]\n): Temporal.ZonedDateTime;\nexport function subBusinessDays(\n input: Temporal.Instant | Temporal.ZonedDateTime | Temporal.PlainDate,\n days: number,\n holidays?: readonly Temporal.PlainDate[]\n): Temporal.ZonedDateTime | Temporal.PlainDate {\n // Narrow each branch to the matching addBusinessDays overload.\n return isPlainDate(input)\n ? addBusinessDays(input, -days, holidays)\n : addBusinessDays(input, -days, holidays);\n}\n"],"mappings":";;;;;;;;AAkCO,SAAS,gBACd,OACA,MACA,UAC6C;AAE7C,SAAO,YAAY,KAAK,IACpB,gBAAgB,OAAO,CAAC,MAAM,QAAQ,IACtC,gBAAgB,OAAO,CAAC,MAAM,QAAQ;AAC5C;","names":[]}
@@ -1,12 +1,12 @@
1
- import {
2
- quarterStartMonth
3
- } from "./chunk-XS2HUADA.js";
4
1
  import {
5
2
  normalizeWithPlainDate
6
3
  } from "./chunk-TCB3IDJM.js";
7
4
  import {
8
5
  getEndOfDay
9
6
  } from "./chunk-NMMMAMKP.js";
7
+ import {
8
+ quarterStartMonth
9
+ } from "./chunk-XS2HUADA.js";
10
10
  import {
11
11
  isPlainDate
12
12
  } from "./chunk-BSVOJYJ7.js";
@@ -32,4 +32,4 @@ function endOfQuarter(input, timezone) {
32
32
  export {
33
33
  endOfQuarter
34
34
  };
35
- //# sourceMappingURL=chunk-MXYAZTDE.js.map
35
+ //# sourceMappingURL=chunk-4FQCY75E.js.map