@northguild/gmt 1.16.0 → 1.18.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 (654) hide show
  1. package/README.md +742 -21
  2. package/dist/calendar/calculate/bucketRange.d.ts +3 -3
  3. package/dist/calendar/calculate/bucketRange.js +6 -6
  4. package/dist/calendar/calculate/floorToZone.d.ts +5 -3
  5. package/dist/calendar/calculate/floorToZone.js +6 -5
  6. package/dist/calendar/calculate/getFiscalPeriod.d.ts +21 -8
  7. package/dist/calendar/calculate/getFiscalPeriod.js +9 -8
  8. package/dist/calendar/calculate/getIsoWeekDate.d.ts +10 -5
  9. package/dist/calendar/calculate/getIsoWeekDate.js +1 -5
  10. package/dist/calendar/calculate/getOrdinalDate.d.ts +10 -3
  11. package/dist/calendar/calculate/getOrdinalDate.js +2 -3
  12. package/dist/calendar/calculate/getQuarter.d.ts +21 -9
  13. package/dist/calendar/calculate/getQuarter.js +8 -12
  14. package/dist/calendar/hours/addOperatingTime.d.ts +53 -0
  15. package/dist/calendar/hours/addOperatingTime.js +59 -0
  16. package/dist/calendar/hours/index.d.ts +7 -0
  17. package/dist/calendar/hours/index.js +7 -0
  18. package/dist/calendar/hours/isOpenAt.d.ts +39 -0
  19. package/dist/calendar/hours/isOpenAt.js +44 -0
  20. package/dist/calendar/hours/nextCloseAt.d.ts +49 -0
  21. package/dist/calendar/hours/nextCloseAt.js +51 -0
  22. package/dist/calendar/hours/nextOpenAt.d.ts +45 -0
  23. package/dist/calendar/hours/nextOpenAt.js +47 -0
  24. package/dist/calendar/hours/operatingIntervals.d.ts +43 -0
  25. package/dist/calendar/hours/operatingIntervals.js +52 -0
  26. package/dist/calendar/hours/operatingTimeBetween.d.ts +40 -0
  27. package/dist/calendar/hours/operatingTimeBetween.js +49 -0
  28. package/dist/calendar/hours/recurringWindows.d.ts +61 -0
  29. package/dist/calendar/hours/recurringWindows.js +80 -0
  30. package/dist/calendar/index.d.ts +1 -0
  31. package/dist/calendar/index.js +1 -0
  32. package/dist/duration/calculate/durationAs.d.ts +13 -8
  33. package/dist/duration/calculate/durationAs.js +4 -8
  34. package/dist/duration/compare/compareDurations.d.ts +12 -6
  35. package/dist/duration/compare/compareDurations.js +3 -6
  36. package/dist/duration/format/formatDuration.d.ts +16 -4
  37. package/dist/duration/format/formatDuration.js +4 -5
  38. package/dist/duration/normalize/normalizeDuration.d.ts +39 -14
  39. package/dist/duration/normalize/normalizeDuration.js +6 -15
  40. package/dist/duration/parse/parseDuration.d.ts +21 -3
  41. package/dist/duration/parse/parseDuration.js +1 -3
  42. package/dist/index.d.ts +2 -0
  43. package/dist/index.js +2 -0
  44. package/dist/instant/convert/classifyLocal.d.ts +1 -1
  45. package/dist/instant/convert/classifyLocal.js +1 -1
  46. package/dist/instant/convert/fromOffsetInstant.d.ts +3 -1
  47. package/dist/instant/convert/fromOffsetInstant.js +6 -12
  48. package/dist/instant/convert/resolveLocal.d.ts +12 -7
  49. package/dist/instant/convert/resolveLocal.js +6 -10
  50. package/dist/instant/convert/toOffsetInstant.d.ts +37 -1
  51. package/dist/instant/convert/toOffsetInstant.js +12 -28
  52. package/dist/intermodal/calculate/billingTimeline.d.ts +114 -0
  53. package/dist/intermodal/calculate/billingTimeline.js +168 -0
  54. package/dist/intermodal/calculate/chargeableDays.d.ts +100 -0
  55. package/dist/intermodal/calculate/chargeableDays.js +96 -0
  56. package/dist/intermodal/calculate/demurrageClock.d.ts +102 -0
  57. package/dist/intermodal/calculate/demurrageClock.js +140 -0
  58. package/dist/intermodal/calculate/freeTimeExpiry.d.ts +67 -0
  59. package/dist/intermodal/calculate/freeTimeExpiry.js +82 -0
  60. package/dist/intermodal/calculate/index.d.ts +4 -0
  61. package/dist/intermodal/calculate/index.js +4 -0
  62. package/dist/intermodal/index.d.ts +2 -0
  63. package/dist/intermodal/index.js +3 -0
  64. package/dist/internal/businessCalendar.d.ts +5 -0
  65. package/dist/internal/businessCalendar.js +5 -1
  66. package/dist/internal/cycleFieldValue.d.ts +6 -4
  67. package/dist/internal/cycleFieldValue.js +6 -4
  68. package/dist/internal/daylightTime.d.ts +33 -0
  69. package/dist/internal/daylightTime.js +164 -0
  70. package/dist/internal/durationUntilString.js +4 -3
  71. package/dist/internal/englishCalendarNames.js +1 -2
  72. package/dist/internal/epochNanoseconds.d.ts +2 -0
  73. package/dist/internal/epochNanoseconds.js +2 -0
  74. package/dist/internal/exactDuration.d.ts +37 -0
  75. package/dist/internal/exactDuration.js +64 -0
  76. package/dist/internal/exactMoment.d.ts +72 -0
  77. package/dist/internal/exactMoment.js +114 -0
  78. package/dist/internal/fiscalCalendar.d.ts +4 -3
  79. package/dist/internal/fiscalCalendar.js +4 -3
  80. package/dist/internal/formatCalendarDays.d.ts +2 -2
  81. package/dist/internal/formatRelativeDuration.d.ts +21 -1
  82. package/dist/internal/formatRelativeDuration.js +47 -7
  83. package/dist/internal/freeTimeLedger.d.ts +93 -0
  84. package/dist/internal/freeTimeLedger.js +262 -0
  85. package/dist/internal/index.d.ts +10 -3
  86. package/dist/internal/index.js +10 -3
  87. package/dist/internal/instantFormatOptions.js +2 -1
  88. package/dist/internal/instantNanoseconds.d.ts +75 -9
  89. package/dist/internal/instantNanoseconds.js +192 -11
  90. package/dist/internal/isoStringBody.d.ts +26 -0
  91. package/dist/internal/isoStringBody.js +22 -2
  92. package/dist/internal/joinDateTimeConnector.d.ts +1 -1
  93. package/dist/internal/monthGridWeekRow.d.ts +2 -1
  94. package/dist/internal/monthGridWeekRow.js +2 -1
  95. package/dist/internal/normalizeTimeZone.d.ts +2 -2
  96. package/dist/internal/normalizeTimeZone.js +2 -2
  97. package/dist/internal/operatingSchedule.d.ts +129 -0
  98. package/dist/internal/operatingSchedule.js +668 -0
  99. package/dist/internal/optionOrDefault.d.ts +18 -0
  100. package/dist/internal/optionOrDefault.js +20 -0
  101. package/dist/internal/patternToken.d.ts +2 -2
  102. package/dist/internal/patternToken.js +28 -13
  103. package/dist/internal/plainDateUntil.js +10 -6
  104. package/dist/internal/punctuality.d.ts +38 -0
  105. package/dist/internal/punctuality.js +59 -0
  106. package/dist/internal/readDateTimeFormatOptions.d.ts +30 -0
  107. package/dist/internal/readDateTimeFormatOptions.js +93 -0
  108. package/dist/internal/resolveDurationRelativeTo.d.ts +4 -0
  109. package/dist/internal/resolveDurationRelativeTo.js +11 -1
  110. package/dist/internal/resolveRelativeRounding.d.ts +17 -6
  111. package/dist/internal/resolveRelativeRounding.js +27 -7
  112. package/dist/internal/resolveRelativeUnit.d.ts +30 -0
  113. package/dist/internal/resolveRelativeUnit.js +40 -0
  114. package/dist/internal/splitStep.d.ts +24 -1
  115. package/dist/internal/splitStep.js +34 -2
  116. package/dist/internal/startOrEndOfZoned.js +2 -3
  117. package/dist/internal/temporalCompat/capabilities.d.ts +26 -0
  118. package/dist/internal/temporalCompat/capabilities.js +35 -3
  119. package/dist/internal/temporalCompat/fieldSearch.js +1 -1
  120. package/dist/internal/temporalCompat/index.d.ts +1 -1
  121. package/dist/internal/temporalCompat/index.js +1 -1
  122. package/dist/internal/temporalCompat/repros.d.ts +1 -1
  123. package/dist/internal/temporalCompat/repros.js +157 -0
  124. package/dist/internal/timestampEvents.d.ts +32 -0
  125. package/dist/internal/timestampEvents.js +76 -0
  126. package/dist/internal/utcZonedDateTime.d.ts +5 -2
  127. package/dist/internal/utcZonedDateTime.js +8 -5
  128. package/dist/internal/wallClockAtOffset.d.ts +22 -0
  129. package/dist/internal/wallClockAtOffset.js +26 -0
  130. package/dist/internal/zonedBucket.js +8 -6
  131. package/dist/internal/zonedLocalDates.js +1 -1
  132. package/dist/internal/zonedTransitionSearch.d.ts +27 -0
  133. package/dist/internal/zonedTransitionSearch.js +218 -0
  134. package/dist/internal/zonedWallClock.d.ts +21 -7
  135. package/dist/internal/zonedWallClock.js +87 -18
  136. package/dist/internal/zonedWallClockDifference.js +5 -4
  137. package/dist/internal/zonedWallClockOperations.d.ts +26 -13
  138. package/dist/internal/zonedWallClockOperations.js +87 -34
  139. package/dist/interval/validate/isValidInterval.d.ts +6 -3
  140. package/dist/interval/validate/isValidInterval.js +6 -3
  141. package/dist/plain/calculate/addDate.d.ts +11 -8
  142. package/dist/plain/calculate/addDate.js +5 -8
  143. package/dist/plain/calculate/addDateTime.d.ts +7 -4
  144. package/dist/plain/calculate/addDateTime.js +1 -4
  145. package/dist/plain/calculate/cycleDate.d.ts +16 -7
  146. package/dist/plain/calculate/cycleDate.js +3 -7
  147. package/dist/plain/calculate/cycleDateTime.d.ts +14 -4
  148. package/dist/plain/calculate/cycleDateTime.js +1 -4
  149. package/dist/plain/calculate/cycleTime.d.ts +10 -5
  150. package/dist/plain/calculate/cycleTime.js +3 -5
  151. package/dist/plain/calculate/diffDate.d.ts +1 -1
  152. package/dist/plain/calculate/diffDate.js +1 -1
  153. package/dist/plain/calculate/diffDateAsDuration.d.ts +1 -1
  154. package/dist/plain/calculate/diffDateAsDuration.js +1 -1
  155. package/dist/plain/calculate/diffDateTime.d.ts +1 -1
  156. package/dist/plain/calculate/diffDateTime.js +1 -1
  157. package/dist/plain/calculate/diffDateTimeAsDuration.d.ts +1 -1
  158. package/dist/plain/calculate/diffDateTimeAsDuration.js +1 -1
  159. package/dist/plain/calculate/diffTime.d.ts +1 -1
  160. package/dist/plain/calculate/diffTime.js +1 -1
  161. package/dist/plain/calculate/endOfDate.d.ts +8 -3
  162. package/dist/plain/calculate/endOfDate.js +1 -3
  163. package/dist/plain/calculate/endOfDateTime.d.ts +15 -5
  164. package/dist/plain/calculate/endOfDateTime.js +1 -5
  165. package/dist/plain/calculate/endOfTime.d.ts +8 -2
  166. package/dist/plain/calculate/endOfTime.js +1 -2
  167. package/dist/plain/calculate/getLocaleWeekYear.d.ts +16 -9
  168. package/dist/plain/calculate/getLocaleWeekYear.js +9 -9
  169. package/dist/plain/calculate/getWeekOfMonth.d.ts +7 -4
  170. package/dist/plain/calculate/getWeekOfMonth.js +7 -4
  171. package/dist/plain/calculate/getWeeksInLocaleWeekYear.d.ts +13 -6
  172. package/dist/plain/calculate/getWeeksInLocaleWeekYear.js +6 -6
  173. package/dist/plain/calculate/getWeeksInMonth.d.ts +5 -2
  174. package/dist/plain/calculate/getWeeksInMonth.js +5 -2
  175. package/dist/plain/calculate/nextWeekday.d.ts +7 -3
  176. package/dist/plain/calculate/nextWeekday.js +1 -3
  177. package/dist/plain/calculate/previousWeekday.d.ts +7 -3
  178. package/dist/plain/calculate/previousWeekday.js +1 -3
  179. package/dist/plain/calculate/roundDate.d.ts +20 -7
  180. package/dist/plain/calculate/roundDate.js +3 -10
  181. package/dist/plain/calculate/roundDateTime.d.ts +22 -8
  182. package/dist/plain/calculate/roundDateTime.js +3 -11
  183. package/dist/plain/calculate/roundTime.d.ts +20 -4
  184. package/dist/plain/calculate/roundTime.js +3 -7
  185. package/dist/plain/calculate/setDate.d.ts +7 -5
  186. package/dist/plain/calculate/setDate.js +1 -5
  187. package/dist/plain/calculate/setDateTime.d.ts +8 -5
  188. package/dist/plain/calculate/setDateTime.js +1 -5
  189. package/dist/plain/calculate/setTime.d.ts +10 -6
  190. package/dist/plain/calculate/setTime.js +4 -6
  191. package/dist/plain/calculate/startOfDate.d.ts +8 -2
  192. package/dist/plain/calculate/startOfDate.js +1 -2
  193. package/dist/plain/calculate/startOfDateTime.d.ts +15 -2
  194. package/dist/plain/calculate/startOfDateTime.js +1 -2
  195. package/dist/plain/calculate/startOfTime.d.ts +8 -1
  196. package/dist/plain/calculate/startOfTime.js +1 -1
  197. package/dist/plain/calculate/subtractDate.d.ts +7 -4
  198. package/dist/plain/calculate/subtractDate.js +1 -4
  199. package/dist/plain/calculate/subtractDateTime.d.ts +7 -4
  200. package/dist/plain/calculate/subtractDateTime.js +1 -4
  201. package/dist/plain/compare/areDateTimesEqualBy.d.ts +13 -5
  202. package/dist/plain/compare/areDateTimesEqualBy.js +6 -5
  203. package/dist/plain/compare/areDatesEqualBy.d.ts +15 -6
  204. package/dist/plain/compare/areDatesEqualBy.js +8 -6
  205. package/dist/plain/compare/isBetweenDate.d.ts +13 -2
  206. package/dist/plain/compare/isBetweenDate.js +4 -4
  207. package/dist/plain/compare/isBetweenDateTime.d.ts +13 -2
  208. package/dist/plain/compare/isBetweenDateTime.js +4 -4
  209. package/dist/plain/compare/isBetweenTime.d.ts +13 -2
  210. package/dist/plain/compare/isBetweenTime.js +4 -4
  211. package/dist/plain/compare/isRelativeDay.d.ts +1 -1
  212. package/dist/plain/compare/isRelativeDay.js +1 -1
  213. package/dist/plain/compare/isThisUnit.d.ts +1 -1
  214. package/dist/plain/compare/isThisUnit.js +1 -1
  215. package/dist/plain/format/formatCalendar.d.ts +21 -14
  216. package/dist/plain/format/formatCalendar.js +21 -16
  217. package/dist/plain/format/formatDate.js +5 -3
  218. package/dist/plain/format/formatDateRange.js +4 -2
  219. package/dist/plain/format/formatDateTime.js +4 -2
  220. package/dist/plain/format/formatDateTimeRange.js +4 -2
  221. package/dist/plain/format/formatDateTimeToParts.d.ts +15 -4
  222. package/dist/plain/format/formatDateTimeToParts.js +10 -6
  223. package/dist/plain/format/formatDateToParts.d.ts +13 -2
  224. package/dist/plain/format/formatDateToParts.js +8 -4
  225. package/dist/plain/format/formatRelativeDate.d.ts +16 -3
  226. package/dist/plain/format/formatRelativeDate.js +26 -15
  227. package/dist/plain/format/formatRelativeDateTime.d.ts +16 -3
  228. package/dist/plain/format/formatRelativeDateTime.js +8 -5
  229. package/dist/plain/format/formatRelativeTime.d.ts +16 -3
  230. package/dist/plain/format/formatRelativeTime.js +21 -13
  231. package/dist/plain/format/formatTime.js +4 -2
  232. package/dist/plain/interval/intervalDifferenceDate.d.ts +9 -0
  233. package/dist/plain/interval/intervalDifferenceDateTime.d.ts +9 -0
  234. package/dist/plain/interval/intervalDifferenceTime.d.ts +9 -0
  235. package/dist/plain/interval/intervalDivideEquallyDate.d.ts +19 -4
  236. package/dist/plain/interval/intervalDivideEquallyDate.js +3 -4
  237. package/dist/plain/interval/intervalDivideEquallyDateTime.d.ts +19 -4
  238. package/dist/plain/interval/intervalDivideEquallyDateTime.js +3 -4
  239. package/dist/plain/interval/intervalDivideEquallyTime.d.ts +19 -4
  240. package/dist/plain/interval/intervalDivideEquallyTime.js +3 -4
  241. package/dist/plain/interval/intervalFromDurationDate.d.ts +16 -3
  242. package/dist/plain/interval/intervalFromDurationDate.js +1 -3
  243. package/dist/plain/interval/intervalFromDurationDateTime.d.ts +16 -3
  244. package/dist/plain/interval/intervalFromDurationDateTime.js +1 -3
  245. package/dist/plain/interval/intervalFromDurationTime.d.ts +9 -0
  246. package/dist/plain/interval/intervalIntersectionDate.d.ts +9 -0
  247. package/dist/plain/interval/intervalIntersectionDateTime.d.ts +9 -0
  248. package/dist/plain/interval/intervalIntersectionTime.d.ts +9 -0
  249. package/dist/plain/interval/intervalSplitAtDate.d.ts +11 -0
  250. package/dist/plain/interval/intervalSplitAtDate.js +2 -0
  251. package/dist/plain/interval/intervalSplitAtDateTime.d.ts +11 -0
  252. package/dist/plain/interval/intervalSplitAtDateTime.js +2 -0
  253. package/dist/plain/interval/intervalSplitAtTime.d.ts +11 -0
  254. package/dist/plain/interval/intervalSplitAtTime.js +2 -0
  255. package/dist/plain/interval/intervalUnionDate.d.ts +9 -0
  256. package/dist/plain/interval/intervalUnionDateTime.d.ts +9 -0
  257. package/dist/plain/interval/intervalUnionTime.d.ts +9 -0
  258. package/dist/plain/interval/intervalXorAllDate.d.ts +9 -0
  259. package/dist/plain/interval/intervalXorAllDateTime.d.ts +9 -0
  260. package/dist/plain/interval/intervalXorAllTime.d.ts +9 -0
  261. package/dist/plain/interval/intervalXorDate.d.ts +9 -0
  262. package/dist/plain/interval/intervalXorDateTime.d.ts +9 -0
  263. package/dist/plain/interval/intervalXorTime.d.ts +9 -0
  264. package/dist/plain/interval/mergeIntervalsDate.d.ts +9 -0
  265. package/dist/plain/interval/mergeIntervalsDateTime.d.ts +9 -0
  266. package/dist/plain/interval/mergeIntervalsTime.d.ts +9 -0
  267. package/dist/plain/interval/splitIntervalByUnitDate.d.ts +23 -7
  268. package/dist/plain/interval/splitIntervalByUnitDate.js +7 -7
  269. package/dist/plain/interval/splitIntervalByUnitDateTime.d.ts +22 -6
  270. package/dist/plain/interval/splitIntervalByUnitDateTime.js +6 -6
  271. package/dist/plain/interval/splitIntervalByUnitTime.d.ts +17 -4
  272. package/dist/plain/interval/splitIntervalByUnitTime.js +1 -4
  273. package/dist/plain/map/mapDatesInRange.d.ts +8 -4
  274. package/dist/plain/map/mapDatesInRange.js +1 -4
  275. package/dist/plain/parse/parseDateTimeWithPattern.d.ts +10 -7
  276. package/dist/plain/parse/parseDateTimeWithPattern.js +10 -7
  277. package/dist/plain/parse/parseDateWithPattern.d.ts +10 -7
  278. package/dist/plain/parse/parseDateWithPattern.js +10 -7
  279. package/dist/plain/parse/parseTimeWithPattern.d.ts +10 -7
  280. package/dist/plain/parse/parseTimeWithPattern.js +10 -7
  281. package/dist/plain/parse/parseUnitFromDate.d.ts +11 -3
  282. package/dist/plain/parse/parseUnitFromDate.js +3 -3
  283. package/dist/plain/parse/parseUnitFromDateTime.d.ts +11 -3
  284. package/dist/plain/parse/parseUnitFromDateTime.js +3 -3
  285. package/dist/plain/parse/parseWeekFromDate.d.ts +10 -6
  286. package/dist/plain/parse/parseWeekFromDate.js +2 -6
  287. package/dist/plain/parse/parseWeekFromDateTime.d.ts +10 -6
  288. package/dist/plain/parse/parseWeekFromDateTime.js +2 -6
  289. package/dist/plain/validate/isValidDateRange.d.ts +19 -4
  290. package/dist/plain/validate/isValidDateRange.js +1 -4
  291. package/dist/plain/validate/isValidDateTimeRange.d.ts +20 -5
  292. package/dist/plain/validate/isValidDateTimeRange.js +2 -5
  293. package/dist/plain/validate/isValidTimeRange.d.ts +20 -5
  294. package/dist/plain/validate/isValidTimeRange.js +2 -5
  295. package/dist/precision/convert/fromExcelSerial.d.ts +10 -4
  296. package/dist/precision/convert/fromExcelSerial.js +4 -5
  297. package/dist/precision/convert/fromNanoseconds.d.ts +1 -1
  298. package/dist/precision/convert/fromNanoseconds.js +1 -1
  299. package/dist/precision/convert/toExcelSerial.d.ts +9 -3
  300. package/dist/precision/convert/toExcelSerial.js +3 -4
  301. package/dist/precision/convert/toNanoseconds.d.ts +11 -6
  302. package/dist/precision/convert/toNanoseconds.js +11 -6
  303. package/dist/precision/validate/isValidInstant.d.ts +12 -3
  304. package/dist/precision/validate/isValidInstant.js +12 -3
  305. package/dist/span/calculate/spanMs.d.ts +10 -4
  306. package/dist/span/calculate/spanMs.js +10 -4
  307. package/dist/span/calculate/spanNs.d.ts +10 -4
  308. package/dist/span/calculate/spanNs.js +10 -4
  309. package/dist/span/validate/isValidSpan.d.ts +8 -3
  310. package/dist/span/validate/isValidSpan.js +8 -3
  311. package/dist/transport/calculate/bestAvailable.d.ts +47 -0
  312. package/dist/transport/calculate/bestAvailable.js +76 -0
  313. package/dist/transport/calculate/crossingTime.d.ts +58 -0
  314. package/dist/transport/calculate/crossingTime.js +76 -0
  315. package/dist/transport/calculate/cutoffAt.d.ts +90 -0
  316. package/dist/transport/calculate/cutoffAt.js +209 -0
  317. package/dist/transport/calculate/cutoffSchedule.d.ts +70 -0
  318. package/dist/transport/calculate/cutoffSchedule.js +71 -0
  319. package/dist/transport/calculate/dwellTime.d.ts +81 -0
  320. package/dist/transport/calculate/dwellTime.js +130 -0
  321. package/dist/transport/calculate/estimateDrift.d.ts +65 -0
  322. package/dist/transport/calculate/estimateDrift.js +75 -0
  323. package/dist/transport/calculate/index.d.ts +10 -0
  324. package/dist/transport/calculate/index.js +10 -0
  325. package/dist/transport/calculate/nextDeparture.d.ts +78 -0
  326. package/dist/transport/calculate/nextDeparture.js +131 -0
  327. package/dist/transport/calculate/punctualityRate.d.ts +42 -0
  328. package/dist/transport/calculate/punctualityRate.js +59 -0
  329. package/dist/transport/calculate/scheduleDelivery.d.ts +150 -0
  330. package/dist/transport/calculate/scheduleDelivery.js +300 -0
  331. package/dist/transport/calculate/transitTime.d.ts +71 -0
  332. package/dist/transport/calculate/transitTime.js +101 -0
  333. package/dist/transport/compare/classifyPunctuality.d.ts +46 -0
  334. package/dist/transport/compare/classifyPunctuality.js +64 -0
  335. package/dist/transport/compare/index.d.ts +4 -0
  336. package/dist/transport/compare/index.js +4 -0
  337. package/dist/transport/compare/isPastCutoff.d.ts +33 -0
  338. package/dist/transport/compare/isPastCutoff.js +48 -0
  339. package/dist/transport/compare/scheduleDeviation.d.ts +37 -0
  340. package/dist/transport/compare/scheduleDeviation.js +53 -0
  341. package/dist/transport/compare/timeToCutoff.d.ts +31 -0
  342. package/dist/transport/compare/timeToCutoff.js +47 -0
  343. package/dist/transport/convert/etaAtZone.d.ts +43 -0
  344. package/dist/transport/convert/etaAtZone.js +58 -0
  345. package/dist/transport/convert/index.d.ts +1 -0
  346. package/dist/transport/convert/index.js +1 -0
  347. package/dist/transport/index.d.ts +4 -0
  348. package/dist/transport/index.js +5 -0
  349. package/dist/types/business-calendar.d.ts +19 -14
  350. package/dist/types/calendar-options.d.ts +15 -3
  351. package/dist/types/date-cycle-field.d.ts +5 -0
  352. package/dist/types/date-duration-unit.d.ts +4 -0
  353. package/dist/types/date-time-cycle-field.d.ts +4 -0
  354. package/dist/types/date-time-duration-units.d.ts +4 -0
  355. package/dist/types/date-time-unit.d.ts +4 -0
  356. package/dist/types/date-unit.d.ts +4 -0
  357. package/dist/types/disambiguation.d.ts +8 -0
  358. package/dist/types/duration-relative-to.d.ts +8 -0
  359. package/dist/types/duration-string-options.d.ts +28 -0
  360. package/dist/types/fiscal-calendar.d.ts +1 -1
  361. package/dist/types/fractional-digit.d.ts +5 -0
  362. package/dist/types/free-time-options.d.ts +44 -0
  363. package/dist/types/index.d.ts +3 -1
  364. package/dist/types/index.js +3 -1
  365. package/dist/types/interval.d.ts +8 -1
  366. package/dist/types/offset.d.ts +9 -0
  367. package/dist/types/operating-schedule.d.ts +71 -0
  368. package/dist/types/operating-schedule.js +0 -0
  369. package/dist/types/overflow.d.ts +6 -0
  370. package/dist/types/relative-rounding-method.d.ts +6 -0
  371. package/dist/types/relative-time-options.d.ts +33 -5
  372. package/dist/types/rounding-options.d.ts +27 -0
  373. package/dist/types/time-cycle-field.d.ts +4 -0
  374. package/dist/types/time-duration-unit.d.ts +4 -0
  375. package/dist/types/time-unit.d.ts +4 -0
  376. package/dist/types/transport-timestamps.d.ts +54 -0
  377. package/dist/types/transport-timestamps.js +0 -0
  378. package/dist/unix/calculate/addUnix.d.ts +19 -5
  379. package/dist/unix/calculate/addUnix.js +1 -5
  380. package/dist/unix/calculate/diffUnix.d.ts +13 -3
  381. package/dist/unix/calculate/diffUnix.js +1 -3
  382. package/dist/unix/calculate/diffUnixAsDuration.d.ts +13 -3
  383. package/dist/unix/calculate/diffUnixAsDuration.js +1 -3
  384. package/dist/unix/calculate/endOfQuarterForUnix.d.ts +13 -3
  385. package/dist/unix/calculate/endOfQuarterForUnix.js +1 -3
  386. package/dist/unix/calculate/endOfUnix.d.ts +20 -4
  387. package/dist/unix/calculate/endOfUnix.js +1 -4
  388. package/dist/unix/calculate/isBetweenUnix.d.ts +26 -4
  389. package/dist/unix/calculate/isBetweenUnix.js +4 -6
  390. package/dist/unix/calculate/roundUnix.d.ts +31 -3
  391. package/dist/unix/calculate/roundUnix.js +3 -6
  392. package/dist/unix/calculate/setUnix.d.ts +35 -9
  393. package/dist/unix/calculate/setUnix.js +4 -13
  394. package/dist/unix/calculate/startOfQuarterForUnix.d.ts +13 -3
  395. package/dist/unix/calculate/startOfQuarterForUnix.js +1 -3
  396. package/dist/unix/calculate/startOfUnix.d.ts +20 -4
  397. package/dist/unix/calculate/startOfUnix.js +1 -4
  398. package/dist/unix/calculate/subtractUnix.d.ts +19 -5
  399. package/dist/unix/calculate/subtractUnix.js +1 -5
  400. package/dist/unix/compare/areUnixEqual.d.ts +7 -1
  401. package/dist/unix/compare/areUnixEqual.js +1 -1
  402. package/dist/unix/compare/areUnixEqualBy.d.ts +24 -7
  403. package/dist/unix/compare/areUnixEqualBy.js +13 -9
  404. package/dist/unix/compare/isAfterUnix.d.ts +7 -1
  405. package/dist/unix/compare/isAfterUnix.js +1 -1
  406. package/dist/unix/compare/isBeforeUnix.d.ts +7 -1
  407. package/dist/unix/compare/isBeforeUnix.js +1 -1
  408. package/dist/unix/convert/convertUnixToPlainDate.d.ts +14 -4
  409. package/dist/unix/convert/convertUnixToPlainDate.js +2 -4
  410. package/dist/unix/convert/convertUnixToPlainDateTime.d.ts +14 -4
  411. package/dist/unix/convert/convertUnixToPlainDateTime.js +2 -4
  412. package/dist/unix/convert/convertUnixToPlainTime.d.ts +14 -4
  413. package/dist/unix/convert/convertUnixToPlainTime.js +2 -4
  414. package/dist/unix/convert/convertUnixToUtc.d.ts +9 -4
  415. package/dist/unix/convert/convertUnixToUtc.js +3 -4
  416. package/dist/unix/convert/convertUnixToZoned.d.ts +10 -5
  417. package/dist/unix/convert/convertUnixToZoned.js +4 -5
  418. package/dist/unix/format/formatCalendarUnix.d.ts +27 -19
  419. package/dist/unix/format/formatCalendarUnix.js +4 -5
  420. package/dist/unix/format/formatRelativeUnix.d.ts +54 -5
  421. package/dist/unix/format/formatRelativeUnix.js +3 -5
  422. package/dist/unix/format/formatUnix.d.ts +24 -6
  423. package/dist/unix/format/formatUnix.js +8 -7
  424. package/dist/unix/get/getUnixNow.d.ts +8 -3
  425. package/dist/unix/get/getUnixNow.js +1 -3
  426. package/dist/unix/interval/intervalCountUnix.d.ts +14 -5
  427. package/dist/unix/interval/intervalCountUnix.js +2 -5
  428. package/dist/unix/interval/intervalDifferenceUnix.d.ts +6 -0
  429. package/dist/unix/interval/intervalDivideEquallyUnix.d.ts +18 -4
  430. package/dist/unix/interval/intervalDivideEquallyUnix.js +5 -4
  431. package/dist/unix/interval/intervalFromDurationUnix.d.ts +33 -5
  432. package/dist/unix/interval/intervalFromDurationUnix.js +6 -5
  433. package/dist/unix/interval/intervalIntersectionUnix.d.ts +6 -0
  434. package/dist/unix/interval/intervalLengthUnix.d.ts +16 -6
  435. package/dist/unix/interval/intervalLengthUnix.js +4 -6
  436. package/dist/unix/interval/intervalOverlappingDaysUnix.d.ts +13 -3
  437. package/dist/unix/interval/intervalOverlappingDaysUnix.js +1 -3
  438. package/dist/unix/interval/intervalSplitAtUnix.d.ts +8 -0
  439. package/dist/unix/interval/intervalSplitAtUnix.js +2 -0
  440. package/dist/unix/interval/intervalUnionUnix.d.ts +6 -0
  441. package/dist/unix/interval/intervalXorAllUnix.d.ts +6 -0
  442. package/dist/unix/interval/intervalXorUnix.d.ts +6 -0
  443. package/dist/unix/interval/mergeIntervalsUnix.d.ts +6 -0
  444. package/dist/unix/interval/splitIntervalByUnitUnix.d.ts +42 -11
  445. package/dist/unix/interval/splitIntervalByUnitUnix.js +21 -16
  446. package/dist/unix/parse/parseDateFromUnix.d.ts +13 -2
  447. package/dist/unix/parse/parseDateFromUnix.js +1 -2
  448. package/dist/unix/parse/parseDayFromUnix.d.ts +14 -2
  449. package/dist/unix/parse/parseDayFromUnix.js +2 -2
  450. package/dist/unix/parse/parseDayOfWeekFromUnix.d.ts +13 -1
  451. package/dist/unix/parse/parseDayOfWeekFromUnix.js +1 -1
  452. package/dist/unix/parse/parseHourFromUnix.d.ts +14 -2
  453. package/dist/unix/parse/parseHourFromUnix.js +2 -2
  454. package/dist/unix/parse/parseMicrosecondFromUnix.d.ts +14 -2
  455. package/dist/unix/parse/parseMicrosecondFromUnix.js +2 -2
  456. package/dist/unix/parse/parseMillisecondFromUnix.d.ts +14 -2
  457. package/dist/unix/parse/parseMillisecondFromUnix.js +2 -2
  458. package/dist/unix/parse/parseMinuteFromUnix.d.ts +14 -2
  459. package/dist/unix/parse/parseMinuteFromUnix.js +2 -2
  460. package/dist/unix/parse/parseMonthFromUnix.d.ts +14 -2
  461. package/dist/unix/parse/parseMonthFromUnix.js +2 -2
  462. package/dist/unix/parse/parseNanosecondFromUnix.d.ts +14 -2
  463. package/dist/unix/parse/parseNanosecondFromUnix.js +2 -2
  464. package/dist/unix/parse/parseSecondFromUnix.d.ts +14 -2
  465. package/dist/unix/parse/parseSecondFromUnix.js +2 -2
  466. package/dist/unix/parse/parseTimeFromUnix.d.ts +13 -2
  467. package/dist/unix/parse/parseTimeFromUnix.js +1 -2
  468. package/dist/unix/parse/parseUnitFromUnix.d.ts +22 -3
  469. package/dist/unix/parse/parseUnitFromUnix.js +2 -3
  470. package/dist/unix/parse/parseWeekFromUnix.d.ts +23 -7
  471. package/dist/unix/parse/parseWeekFromUnix.js +3 -7
  472. package/dist/unix/parse/parseYearFromUnix.d.ts +14 -2
  473. package/dist/unix/parse/parseYearFromUnix.js +2 -2
  474. package/dist/unix/validate/isValidUnixRange.d.ts +20 -4
  475. package/dist/unix/validate/isValidUnixRange.js +1 -4
  476. package/dist/utc/calculate/addUtc.d.ts +7 -4
  477. package/dist/utc/calculate/addUtc.js +1 -4
  478. package/dist/utc/calculate/diffUtc.d.ts +1 -1
  479. package/dist/utc/calculate/diffUtc.js +1 -1
  480. package/dist/utc/calculate/diffUtcAsDuration.d.ts +1 -1
  481. package/dist/utc/calculate/diffUtcAsDuration.js +1 -1
  482. package/dist/utc/calculate/endOfUtc.d.ts +16 -3
  483. package/dist/utc/calculate/endOfUtc.js +2 -3
  484. package/dist/utc/calculate/isBetweenUtc.d.ts +13 -2
  485. package/dist/utc/calculate/isBetweenUtc.js +4 -4
  486. package/dist/utc/calculate/roundUtc.d.ts +26 -9
  487. package/dist/utc/calculate/roundUtc.js +3 -12
  488. package/dist/utc/calculate/setUtc.d.ts +7 -4
  489. package/dist/utc/calculate/setUtc.js +1 -4
  490. package/dist/utc/calculate/startOfUtc.d.ts +15 -2
  491. package/dist/utc/calculate/startOfUtc.js +1 -2
  492. package/dist/utc/calculate/subtractUtc.d.ts +7 -4
  493. package/dist/utc/calculate/subtractUtc.js +1 -4
  494. package/dist/utc/compare/areUtcEqualBy.d.ts +9 -3
  495. package/dist/utc/compare/areUtcEqualBy.js +2 -3
  496. package/dist/utc/convert/convertUtcToPlainDate.d.ts +8 -3
  497. package/dist/utc/convert/convertUtcToPlainDate.js +5 -6
  498. package/dist/utc/convert/convertUtcToPlainDateTime.d.ts +8 -3
  499. package/dist/utc/convert/convertUtcToPlainDateTime.js +5 -6
  500. package/dist/utc/convert/convertUtcToPlainTime.d.ts +8 -3
  501. package/dist/utc/convert/convertUtcToPlainTime.js +5 -6
  502. package/dist/utc/convert/convertUtcToUnix.d.ts +9 -4
  503. package/dist/utc/convert/convertUtcToUnix.js +3 -4
  504. package/dist/utc/convert/convertUtcToZoned.d.ts +1 -1
  505. package/dist/utc/convert/convertUtcToZoned.js +1 -1
  506. package/dist/utc/format/formatCalendarUtc.d.ts +19 -8
  507. package/dist/utc/format/formatCalendarUtc.js +8 -6
  508. package/dist/utc/format/formatHttp.d.ts +1 -1
  509. package/dist/utc/format/formatHttp.js +1 -1
  510. package/dist/utc/format/formatRelativeUtc.d.ts +30 -10
  511. package/dist/utc/format/formatRelativeUtc.js +9 -11
  512. package/dist/utc/format/formatUtc.d.ts +17 -15
  513. package/dist/utc/format/formatUtc.js +8 -8
  514. package/dist/utc/interval/intervalDifferenceUtc.d.ts +6 -0
  515. package/dist/utc/interval/intervalDivideEquallyUtc.d.ts +18 -4
  516. package/dist/utc/interval/intervalDivideEquallyUtc.js +5 -4
  517. package/dist/utc/interval/intervalFromDurationUtc.d.ts +13 -3
  518. package/dist/utc/interval/intervalFromDurationUtc.js +1 -3
  519. package/dist/utc/interval/intervalIntersectionUtc.d.ts +6 -0
  520. package/dist/utc/interval/intervalSplitAtUtc.d.ts +8 -0
  521. package/dist/utc/interval/intervalSplitAtUtc.js +2 -0
  522. package/dist/utc/interval/intervalUnionUtc.d.ts +6 -0
  523. package/dist/utc/interval/intervalXorAllUtc.d.ts +6 -0
  524. package/dist/utc/interval/intervalXorUtc.d.ts +6 -0
  525. package/dist/utc/interval/mergeIntervalsUtc.d.ts +6 -0
  526. package/dist/utc/interval/splitIntervalByUnitUtc.d.ts +19 -6
  527. package/dist/utc/interval/splitIntervalByUnitUtc.js +6 -6
  528. package/dist/utc/parse/parseDateFromUtc.d.ts +7 -3
  529. package/dist/utc/parse/parseDateFromUtc.js +1 -3
  530. package/dist/utc/parse/parseDayFromUtc.d.ts +7 -3
  531. package/dist/utc/parse/parseDayFromUtc.js +1 -3
  532. package/dist/utc/parse/parseDayOfWeekFromUtc.d.ts +7 -3
  533. package/dist/utc/parse/parseDayOfWeekFromUtc.js +4 -6
  534. package/dist/utc/parse/parseHourFromUtc.d.ts +7 -3
  535. package/dist/utc/parse/parseHourFromUtc.js +1 -3
  536. package/dist/utc/parse/parseHttp.d.ts +1 -1
  537. package/dist/utc/parse/parseHttp.js +1 -1
  538. package/dist/utc/parse/parseMicrosecondFromUtc.d.ts +7 -3
  539. package/dist/utc/parse/parseMicrosecondFromUtc.js +1 -3
  540. package/dist/utc/parse/parseMillisecondFromUtc.d.ts +7 -3
  541. package/dist/utc/parse/parseMillisecondFromUtc.js +1 -3
  542. package/dist/utc/parse/parseMinuteFromUtc.d.ts +7 -3
  543. package/dist/utc/parse/parseMinuteFromUtc.js +1 -3
  544. package/dist/utc/parse/parseMonthFromUtc.d.ts +7 -3
  545. package/dist/utc/parse/parseMonthFromUtc.js +1 -3
  546. package/dist/utc/parse/parseNanosecondFromUtc.d.ts +7 -3
  547. package/dist/utc/parse/parseNanosecondFromUtc.js +1 -3
  548. package/dist/utc/parse/parseSecondFromUtc.d.ts +7 -3
  549. package/dist/utc/parse/parseSecondFromUtc.js +1 -3
  550. package/dist/utc/parse/parseTimeFromUtc.d.ts +8 -3
  551. package/dist/utc/parse/parseTimeFromUtc.js +5 -6
  552. package/dist/utc/parse/parseUnitFromUtc.d.ts +17 -5
  553. package/dist/utc/parse/parseUnitFromUtc.js +6 -8
  554. package/dist/utc/parse/parseWeekFromUtc.d.ts +18 -10
  555. package/dist/utc/parse/parseWeekFromUtc.js +7 -13
  556. package/dist/utc/parse/parseYearFromUtc.d.ts +7 -3
  557. package/dist/utc/parse/parseYearFromUtc.js +1 -3
  558. package/dist/utc/validate/isValidUtcRange.d.ts +16 -5
  559. package/dist/utc/validate/isValidUtcRange.js +2 -5
  560. package/dist/zoned/calculate/addZoned.d.ts +20 -10
  561. package/dist/zoned/calculate/addZoned.js +6 -13
  562. package/dist/zoned/calculate/cycleZoned.d.ts +33 -8
  563. package/dist/zoned/calculate/cycleZoned.js +1 -8
  564. package/dist/zoned/calculate/diffZoned.d.ts +1 -1
  565. package/dist/zoned/calculate/diffZoned.js +1 -1
  566. package/dist/zoned/calculate/diffZonedAsDuration.d.ts +1 -1
  567. package/dist/zoned/calculate/diffZonedAsDuration.js +1 -1
  568. package/dist/zoned/calculate/endOfQuarterForZoned.d.ts +9 -2
  569. package/dist/zoned/calculate/endOfQuarterForZoned.js +4 -5
  570. package/dist/zoned/calculate/endOfZoned.d.ts +16 -3
  571. package/dist/zoned/calculate/endOfZoned.js +2 -3
  572. package/dist/zoned/calculate/getLocaleZonedEndOfWeek.d.ts +10 -3
  573. package/dist/zoned/calculate/getLocaleZonedEndOfWeek.js +5 -6
  574. package/dist/zoned/calculate/getLocaleZonedStartOfWeek.d.ts +7 -1
  575. package/dist/zoned/calculate/getLocaleZonedStartOfWeek.js +3 -4
  576. package/dist/zoned/calculate/roundZoned.d.ts +21 -4
  577. package/dist/zoned/calculate/roundZoned.js +3 -7
  578. package/dist/zoned/calculate/setZoned.d.ts +25 -8
  579. package/dist/zoned/calculate/setZoned.js +4 -12
  580. package/dist/zoned/calculate/startOfQuarterForZoned.d.ts +7 -2
  581. package/dist/zoned/calculate/startOfQuarterForZoned.js +3 -5
  582. package/dist/zoned/calculate/startOfZoned.d.ts +15 -3
  583. package/dist/zoned/calculate/startOfZoned.js +1 -3
  584. package/dist/zoned/calculate/subtractZoned.d.ts +20 -10
  585. package/dist/zoned/calculate/subtractZoned.js +6 -13
  586. package/dist/zoned/compare/areZonedEqualBy.d.ts +14 -5
  587. package/dist/zoned/compare/areZonedEqualBy.js +7 -5
  588. package/dist/zoned/compare/isBetweenZoned.d.ts +13 -1
  589. package/dist/zoned/compare/isBetweenZoned.js +4 -3
  590. package/dist/zoned/compare/isInDaylightSaving.d.ts +38 -11
  591. package/dist/zoned/compare/isInDaylightSaving.js +40 -44
  592. package/dist/zoned/convert/convertPlainDateTimeToZoned.d.ts +18 -5
  593. package/dist/zoned/convert/convertPlainDateTimeToZoned.js +6 -11
  594. package/dist/zoned/convert/convertZonedToUnix.d.ts +9 -4
  595. package/dist/zoned/convert/convertZonedToUnix.js +2 -4
  596. package/dist/zoned/convert/convertZonedToZoned.d.ts +1 -1
  597. package/dist/zoned/convert/convertZonedToZoned.js +1 -1
  598. package/dist/zoned/format/formatCalendarZoned.d.ts +18 -12
  599. package/dist/zoned/format/formatCalendarZoned.js +13 -9
  600. package/dist/zoned/format/formatRelativeZoned.d.ts +41 -12
  601. package/dist/zoned/format/formatRelativeZoned.js +7 -4
  602. package/dist/zoned/format/formatRfc2822.d.ts +2 -2
  603. package/dist/zoned/format/formatRfc2822.js +2 -2
  604. package/dist/zoned/format/formatRfc3339.d.ts +2 -3
  605. package/dist/zoned/format/formatRfc3339.js +2 -3
  606. package/dist/zoned/format/formatTimeZoneName.d.ts +12 -3
  607. package/dist/zoned/format/formatTimeZoneName.js +5 -4
  608. package/dist/zoned/format/formatZonedDateTime.js +2 -1
  609. package/dist/zoned/format/formatZonedRange.js +2 -1
  610. package/dist/zoned/format/formatZonedToParts.d.ts +15 -4
  611. package/dist/zoned/format/formatZonedToParts.js +8 -5
  612. package/dist/zoned/get/getDstTransitions.d.ts +9 -10
  613. package/dist/zoned/get/getDstTransitions.js +12 -3
  614. package/dist/zoned/get/getTimeZoneOffset.d.ts +4 -1
  615. package/dist/zoned/get/getTimeZoneOffset.js +6 -3
  616. package/dist/zoned/get/getZonedNow.d.ts +13 -1
  617. package/dist/zoned/get/getZonedNow.js +12 -3
  618. package/dist/zoned/interval/intervalDifferenceZoned.d.ts +9 -0
  619. package/dist/zoned/interval/intervalDivideEquallyZoned.d.ts +22 -4
  620. package/dist/zoned/interval/intervalDivideEquallyZoned.js +6 -4
  621. package/dist/zoned/interval/intervalFromDurationZoned.d.ts +29 -10
  622. package/dist/zoned/interval/intervalFromDurationZoned.js +6 -13
  623. package/dist/zoned/interval/intervalIntersectionZoned.d.ts +9 -0
  624. package/dist/zoned/interval/intervalSplitAtZoned.d.ts +11 -0
  625. package/dist/zoned/interval/intervalSplitAtZoned.js +2 -0
  626. package/dist/zoned/interval/intervalUnionZoned.d.ts +9 -0
  627. package/dist/zoned/interval/intervalXorAllZoned.d.ts +9 -0
  628. package/dist/zoned/interval/intervalXorZoned.d.ts +9 -0
  629. package/dist/zoned/interval/mergeIntervalsZoned.d.ts +9 -0
  630. package/dist/zoned/interval/splitIntervalByUnitZoned.d.ts +27 -6
  631. package/dist/zoned/interval/splitIntervalByUnitZoned.js +11 -6
  632. package/dist/zoned/map/mapZonedDatesInRange.d.ts +9 -4
  633. package/dist/zoned/map/mapZonedDatesInRange.js +2 -4
  634. package/dist/zoned/parse/parseRfc2822.d.ts +1 -1
  635. package/dist/zoned/parse/parseRfc2822.js +1 -1
  636. package/dist/zoned/parse/parseUnitFromZoned.d.ts +9 -3
  637. package/dist/zoned/parse/parseUnitFromZoned.js +1 -3
  638. package/dist/zoned/parse/parseWeekFromZoned.d.ts +10 -3
  639. package/dist/zoned/parse/parseWeekFromZoned.js +2 -3
  640. package/dist/zoned/validate/hasDaylightSaving.d.ts +42 -11
  641. package/dist/zoned/validate/hasDaylightSaving.js +47 -31
  642. package/dist/zoned/validate/isValidZonedDateTime.d.ts +13 -0
  643. package/dist/zoned/validate/isValidZonedDateTime.js +14 -1
  644. package/dist/zoned/validate/isValidZonedRange.d.ts +15 -4
  645. package/dist/zoned/validate/isValidZonedRange.js +1 -4
  646. package/package.json +53 -5
  647. package/skills/gmt-arithmetic/SKILL.md +1 -1
  648. package/skills/gmt-basics/SKILL.md +10 -1
  649. package/skills/gmt-integration/SKILL.md +10 -5
  650. package/skills/gmt-timezone/SKILL.md +210 -14
  651. package/dist/internal/resolveReadingTimeZone.d.ts +0 -11
  652. package/dist/internal/resolveReadingTimeZone.js +0 -18
  653. package/dist/types/duration-unit.d.ts +0 -5
  654. /package/dist/types/{duration-unit.js → free-time-options.js} +0 -0
@@ -1,32 +1,9 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
- import { formatUtcOffset, isoStringBody, parseInstantNanoseconds, zonedDateTimeFrom, } from "../../internal/index.js";
2
+ import { formatUtcOffset, isoStringBody, parseInstantNanoseconds, TIME_ZONE_ANNOTATION, zonedDateTimeFrom, } from "../../internal/index.js";
3
3
  import { utcOffset } from "../../regex/index.js";
4
4
  import { isValidTimeZone } from "../../zoned/validate/index.js";
5
- /**
6
- * An absolute instant paired with the local UTC offset in force where the event happened.
7
- *
8
- * @remarks Members:
9
- *
10
- * | Member | Type | Description |
11
- * | --- | --- | --- |
12
- * | `instant` | `string` | UTC instant, ISO 8601 ending in `Z` (e.g. `2024-07-15T16:00:00Z`). Orders events globally. |
13
- * | `offset` | `string` | UTC offset in force where the event happened, `±HH:MM` (or `±HH:MM:SS` for a pre-1972 zone that did not run on a whole minute). Renders the event as the human on the ground saw it. |
14
- * | `timeZone` | `string \| undefined` | IANA zone identifier, when one is known. Absent from most feeds, so absent from most pairs. |
15
- *
16
- * Neither `instant` nor `offset` derives from the other, which is why both are stored. It is
17
- * the shape GS1 EPCIS 2.0 (`eventTime` + a required `eventTimeZoneOffset`), UN/EDIFACT DTM
18
- * (qualifier `303`/`304`) and DICOM (`DT` + `&ZZXX`) all exchange.
19
- *
20
- * @example
21
- * import { OffsetInstant } from "@northguild/gmt/instant";
22
- * const pair: OffsetInstant = {
23
- * instant: "2024-07-15T16:00:00Z",
24
- * offset: "-04:00",
25
- * timeZone: "America/New_York",
26
- * };
27
- */
28
5
  /** A leading RFC 9557 time zone annotation: `[zone]` or `[!zone]`, with no `=`. */
29
- const timeZoneAnnotation = /^\[!?[^\]=]+\]/;
6
+ const timeZoneAnnotation = new RegExp(`^${TIME_ZONE_ANNOTATION}`);
30
7
  /**
31
8
  * Split an ISO 8601 instant string into the instant-plus-offset pair the world exchanges.
32
9
  *
@@ -69,10 +46,15 @@ const timeZoneAnnotation = /^\[!?[^\]=]+\]/;
69
46
  * rounding it would put the pair 30 seconds from the event it describes. Such a zone's
70
47
  * *string* still carries the rounded `-00:45`, because RFC 9557 caps a written offset at
71
48
  * minutes; the bracketed zone is what resolves it, so the instant stays exact.
49
+ * - A bracketed zone is checked as `Temporal.ZonedDateTime.from` checks it, which also rejects
50
+ * a local date of −271821-04-19. A zone west of Greenwich shows that date for the first hours
51
+ * of the instant range, so a zoned string written there
52
+ * (`-271821-04-19T23:59:00-00:01[Europe/London]`) returns null, although `isValidInstant`
53
+ * accepts it. Pass the instant in `Z` form with `timeZone` instead.
72
54
  * - Returns null on invalid input, not a zero-offset pair — `+00:00` is a real offset.
73
55
  *
74
56
  * @param value ISO 8601 instant string, with an offset designator and optionally a bracketed zone
75
- * @param timeZone optional IANA zone identifier to read the offset in
57
+ * @param timeZone optional IANA name or UTC offset to read the offset in
76
58
  * @returns `{ instant, offset, timeZone? }`, or null on invalid input
77
59
  *
78
60
  * @example toOffsetInstant("2024-07-15T12:00:00-04:00[America/New_York]") // { instant: "2024-07-15T16:00:00Z", offset: "-04:00", timeZone: "America/New_York" }
@@ -84,6 +66,8 @@ const timeZoneAnnotation = /^\[!?[^\]=]+\]/;
84
66
  * @example toOffsetInstant("1969-12-31T23:15:30-00:45[Africa/Monrovia]") // { instant: "1970-01-01T00:00:00Z", offset: "-00:44:30", timeZone: "Africa/Monrovia" } — the zone, not the rounded offset, fixes the instant
85
67
  * @example toOffsetInstant("2024-07-15T12:00:00-04:00[-04:00]") // { instant: "2024-07-15T16:00:00Z", offset: "-04:00" } — a bracketed offset is not a zone, so no timeZone field
86
68
  * @example toOffsetInstant("2024-07-15T12:00:00-05:00[America/New_York]") // null (offset contradicts the bracketed zone)
69
+ * @example toOffsetInstant("-271821-04-19T23:59:00-00:01[Europe/London]") // null (a bracketed zone on a local date before Temporal's date range)
70
+ * @example toOffsetInstant("-271821-04-20T00:00:15Z", "Europe/London") // { instant: "-271821-04-20T00:00:15Z", offset: "-00:01:15", timeZone: "Europe/London" }
87
71
  * @example toOffsetInstant("2024-07-15T12:00:00-04:00[foo=bar]") // { instant: "2024-07-15T16:00:00Z", offset: "-04:00" } — an elective annotation is ignored
88
72
  * @example toOffsetInstant("2024-07-15T12:00:00-04:00[!foo=bar]") // null (an unknown critical annotation)
89
73
  * @example toOffsetInstant("2024-07-15T12:00:00") // null (no offset designator)
@@ -103,8 +87,8 @@ export function toOffsetInstant(value, timeZone) {
103
87
  return null;
104
88
  }
105
89
  try {
106
- // `parseInstantNanoseconds` reads the offset and ignores the bracket, so a self-
107
- // contradictory string parses fine as an instant. `ZonedDateTime.from` is what checks
90
+ // `parseInstantNanoseconds` does not validate the bracket, so a self-contradictory string
91
+ // parses fine as an instant. `ZonedDateTime.from` is what checks
108
92
  // the two agree, and it runs even when `timeZone` overrides the bracketed zone.
109
93
  // Only a time zone annotation makes the string zoned: it is the first annotation, and the
110
94
  // only kind with no `=` (RFC 9557 §4.1). A calendar or elective annotation alone leaves an
@@ -0,0 +1,114 @@
1
+ /** The dates a billing timeline is counted from: the anchor, and the invoice and request once they exist. */
2
+ export interface BillingDates {
3
+ /**
4
+ * The date the issue window is counted from, as an ISO date, such as the date the charge was
5
+ * last incurred or, for a re-bill, the issuance date of the invoice received.
6
+ */
7
+ anchorOn: string;
8
+ /**
9
+ * The date the invoice was issued, once it has been, as an ISO date.
10
+ *
11
+ * @defaultValue None. `issuedByDeadline` and `disputeDeadline` are `null`.
12
+ */
13
+ invoiceIssuedOn?: string;
14
+ /**
15
+ * The date the dispute request was received, once it has been, as an ISO date. It needs
16
+ * `invoiceIssuedOn` and may not precede it.
17
+ *
18
+ * @defaultValue None. `requestedByDeadline` and `resolutionDeadline` are `null`.
19
+ */
20
+ requestReceivedOn?: string;
21
+ }
22
+ /** The three windows the caller supplies, in calendar days, none defaulted, and an optional agreed resolution date. */
23
+ export interface BillingWindows {
24
+ /** The days from `anchorOn` within which the invoice must be issued. */
25
+ issueDays: number;
26
+ /** The days from `invoiceIssuedOn` within which a dispute may be raised. */
27
+ disputeDays: number;
28
+ /** The days from `requestReceivedOn` within which the dispute must be resolved. */
29
+ resolutionDays: number;
30
+ /**
31
+ * A resolution date the parties agreed instead, as an ISO date on or after `requestReceivedOn`;
32
+ * it replaces the computed one.
33
+ *
34
+ * @defaultValue None. `resolutionDeadline` is `requestReceivedOn + resolutionDays`.
35
+ */
36
+ agreedResolutionOn?: string;
37
+ }
38
+ /** What `billingTimeline` returns: each deadline as an ISO date, and each comparison once its date exists. */
39
+ export interface BillingDeadlines {
40
+ /** The last date the invoice may be issued: `anchorOn + issueDays`. */
41
+ invoiceDeadline: string;
42
+ /** Whether `invoiceIssuedOn` is on or before `invoiceDeadline`; `null` until an invoice date exists. */
43
+ issuedByDeadline: boolean | null;
44
+ /**
45
+ * The last date a dispute may be raised: `invoiceIssuedOn + disputeDays`; `null` until an invoice
46
+ * date exists.
47
+ */
48
+ disputeDeadline: string | null;
49
+ /** Whether `requestReceivedOn` is on or before `disputeDeadline`; `null` until a request date exists. */
50
+ requestedByDeadline: boolean | null;
51
+ /**
52
+ * The last date the dispute must be resolved: `requestReceivedOn + resolutionDays`, or
53
+ * `agreedResolutionOn`; `null` until a request date exists.
54
+ */
55
+ resolutionDeadline: string | null;
56
+ }
57
+ /**
58
+ * Lay out the deadline chain around a demurrage or detention invoice: the last date it may be
59
+ * issued, the last date it may be disputed, and the last date the dispute must be resolved.
60
+ *
61
+ * A billing regime or service contract can set up to three windows around an invoice: one to
62
+ * issue it, one to dispute it, and one to resolve the dispute. The number of days in each is the
63
+ * caller's fact; GMT carries none of them. The arithmetic is this function's: each deadline is a
64
+ * date, counted in calendar days from a date, with the anchor as day zero and the deadline day
65
+ * itself inside the window.
66
+ *
67
+ * - **Day zero is the anchor and the deadline is `anchor + days`** on the ISO 8601 calendar
68
+ * (`Temporal.PlainDate.add`); a date is "by the deadline" when
69
+ * `Temporal.PlainDate.compare(date, deadline) <= 0`. That is this function's stated contract,
70
+ * not a reading of any rule; a regime that counts differently passes a different number.
71
+ * - **Deadlines are dates, never instants.** Reduce an instant to the billing party's local date
72
+ * first with `convertUtcToPlainDate(instant, { timeZone })`; this function does not guess a
73
+ * zone. `anchorOn` is whatever date the caller counts from, such as the last charged date
74
+ * (`chargeableDays(...).chargedDates.at(-1)`) or, for a party re-billing a charge it was
75
+ * itself billed, the issuance date of the invoice it received.
76
+ * - **Windows have no defaults.** Each is a safe integer of at least `0`; a missing, negative or
77
+ * non-integer window returns `null`, because a silently defaulted window is a wrong deadline.
78
+ * - **The chain fills in as its dates exist.** With only `anchorOn` the result is a forecast:
79
+ * `invoiceDeadline` is set and every other field is `null`. An invoice date sets
80
+ * `issuedByDeadline` and `disputeDeadline`; a request date sets `requestedByDeadline` and
81
+ * `resolutionDeadline`. An explicit `undefined` is an omission; any other value must be a
82
+ * valid ISO date.
83
+ * - **The booleans compare dates and say nothing else.** Whether a charge is payable, whether a
84
+ * dispute must be heard, and any consequence are the consumer's. GMT computes dates, not
85
+ * liability.
86
+ * - **`agreedResolutionOn` replaces the computed `resolutionDeadline`** when given. It must be a
87
+ * valid date on or after `requestReceivedOn`, else `null`; it is validated even when no
88
+ * request exists, but cannot act without one.
89
+ * - **A request cannot precede the invoice it disputes.** `requestReceivedOn` without
90
+ * `invoiceIssuedOn`, or earlier than it, is a data error and returns `null`. An invoice earlier
91
+ * than the anchor is allowed: an invoice may be issued while charges still accrue.
92
+ * - Every emitted date is canonical bare ISO (`Temporal.PlainDate#toString()`), so an input
93
+ * annotation such as `[u-ca=iso8601]` does not reach the output, as `addDate` behaves.
94
+ * - Returns `null` when `dates` or `windows` is not an object, `anchorOn` or a given optional
95
+ * date is not a valid ISO date, a window is missing or not a safe integer of at least `0`, a
96
+ * request exists without an invoice or before it, `agreedResolutionOn` is before the request,
97
+ * or a deadline would leave Temporal's range.
98
+ *
99
+ * @param dates The anchor date, and the invoice and request dates once they exist
100
+ * @param windows The three calendar-day windows, none defaulted, and an agreed resolution date
101
+ * @returns { invoiceDeadline, issuedByDeadline, disputeDeadline, requestedByDeadline, resolutionDeadline }, or null on invalid input
102
+ *
103
+ * @example billingTimeline({ anchorOn: "2026-03-01" }, { issueDays: 30, disputeDays: 30, resolutionDays: 30 }) // { invoiceDeadline: "2026-03-31", issuedByDeadline: null, disputeDeadline: null, requestedByDeadline: null, resolutionDeadline: null } (no invoice yet: a forecast)
104
+ * @example billingTimeline({ anchorOn: "2026-03-01", invoiceIssuedOn: "2026-03-31" }, { issueDays: 30, disputeDays: 30, resolutionDays: 30 }) // { invoiceDeadline: "2026-03-31", issuedByDeadline: true, disputeDeadline: "2026-04-30", requestedByDeadline: null, resolutionDeadline: null } (day 30 is the last day by the deadline)
105
+ * @example billingTimeline({ anchorOn: "2026-03-01", invoiceIssuedOn: "2026-04-01" }, { issueDays: 30, disputeDays: 30, resolutionDays: 30 }) // { invoiceDeadline: "2026-03-31", issuedByDeadline: false, disputeDeadline: "2026-05-01", requestedByDeadline: null, resolutionDeadline: null } (day 31)
106
+ * @example billingTimeline({ anchorOn: "2026-03-01", invoiceIssuedOn: "2026-03-20", requestReceivedOn: "2026-04-19" }, { issueDays: 30, disputeDays: 30, resolutionDays: 30 }) // { invoiceDeadline: "2026-03-31", issuedByDeadline: true, disputeDeadline: "2026-04-19", requestedByDeadline: true, resolutionDeadline: "2026-05-19" }
107
+ * @example billingTimeline({ anchorOn: "2026-03-01", invoiceIssuedOn: "2026-03-20", requestReceivedOn: "2026-04-20" }, { issueDays: 30, disputeDays: 30, resolutionDays: 30, agreedResolutionOn: "2026-06-01" }) // { invoiceDeadline: "2026-03-31", issuedByDeadline: true, disputeDeadline: "2026-04-19", requestedByDeadline: false, resolutionDeadline: "2026-06-01" } (an agreed date replaces the computed one)
108
+ * @example billingTimeline({ anchorOn: "2026-03-10", invoiceIssuedOn: "2026-04-05" }, { issueDays: 30, disputeDays: 30, resolutionDays: 30 }) // { invoiceDeadline: "2026-04-09", issuedByDeadline: true, disputeDeadline: "2026-05-05", requestedByDeadline: null, resolutionDeadline: null } (a re-bill anchored on the invoice it received, not on the charge)
109
+ * @example billingTimeline({ anchorOn: "2026-03-01", invoiceIssuedOn: "2026-03-05", requestReceivedOn: "2026-03-18" }, { issueDays: 14, disputeDays: 14, resolutionDays: 45 }) // { invoiceDeadline: "2026-03-15", issuedByDeadline: true, disputeDeadline: "2026-03-19", requestedByDeadline: true, resolutionDeadline: "2026-05-02" } (a service contract's own windows)
110
+ * @example billingTimeline({ anchorOn: "2028-01-30" }, { issueDays: 30, disputeDays: 30, resolutionDays: 30 }) // { invoiceDeadline: "2028-02-29", issuedByDeadline: null, disputeDeadline: null, requestedByDeadline: null, resolutionDeadline: null } (calendar days across a leap day)
111
+ * @example billingTimeline({ anchorOn: "2026-03-01", invoiceIssuedOn: "2026-03-31" }, { disputeDays: 30, resolutionDays: 30 }) // null (issueDays has no default)
112
+ * @example billingTimeline({ anchorOn: "2026-03-01", requestReceivedOn: "2026-04-19" }, { issueDays: 30, disputeDays: 30, resolutionDays: 30 }) // null (a request cannot precede the invoice it disputes)
113
+ */
114
+ export declare function billingTimeline(dates: BillingDates, windows: BillingWindows): BillingDeadlines | null;
@@ -0,0 +1,168 @@
1
+ import { Temporal } from "@js-temporal/polyfill";
2
+ import { isObject } from "../../internal/index.js";
3
+ import { isValidDate } from "../../plain/validate/isValidDate.js";
4
+ /**
5
+ * Lay out the deadline chain around a demurrage or detention invoice: the last date it may be
6
+ * issued, the last date it may be disputed, and the last date the dispute must be resolved.
7
+ *
8
+ * A billing regime or service contract can set up to three windows around an invoice: one to
9
+ * issue it, one to dispute it, and one to resolve the dispute. The number of days in each is the
10
+ * caller's fact; GMT carries none of them. The arithmetic is this function's: each deadline is a
11
+ * date, counted in calendar days from a date, with the anchor as day zero and the deadline day
12
+ * itself inside the window.
13
+ *
14
+ * - **Day zero is the anchor and the deadline is `anchor + days`** on the ISO 8601 calendar
15
+ * (`Temporal.PlainDate.add`); a date is "by the deadline" when
16
+ * `Temporal.PlainDate.compare(date, deadline) <= 0`. That is this function's stated contract,
17
+ * not a reading of any rule; a regime that counts differently passes a different number.
18
+ * - **Deadlines are dates, never instants.** Reduce an instant to the billing party's local date
19
+ * first with `convertUtcToPlainDate(instant, { timeZone })`; this function does not guess a
20
+ * zone. `anchorOn` is whatever date the caller counts from, such as the last charged date
21
+ * (`chargeableDays(...).chargedDates.at(-1)`) or, for a party re-billing a charge it was
22
+ * itself billed, the issuance date of the invoice it received.
23
+ * - **Windows have no defaults.** Each is a safe integer of at least `0`; a missing, negative or
24
+ * non-integer window returns `null`, because a silently defaulted window is a wrong deadline.
25
+ * - **The chain fills in as its dates exist.** With only `anchorOn` the result is a forecast:
26
+ * `invoiceDeadline` is set and every other field is `null`. An invoice date sets
27
+ * `issuedByDeadline` and `disputeDeadline`; a request date sets `requestedByDeadline` and
28
+ * `resolutionDeadline`. An explicit `undefined` is an omission; any other value must be a
29
+ * valid ISO date.
30
+ * - **The booleans compare dates and say nothing else.** Whether a charge is payable, whether a
31
+ * dispute must be heard, and any consequence are the consumer's. GMT computes dates, not
32
+ * liability.
33
+ * - **`agreedResolutionOn` replaces the computed `resolutionDeadline`** when given. It must be a
34
+ * valid date on or after `requestReceivedOn`, else `null`; it is validated even when no
35
+ * request exists, but cannot act without one.
36
+ * - **A request cannot precede the invoice it disputes.** `requestReceivedOn` without
37
+ * `invoiceIssuedOn`, or earlier than it, is a data error and returns `null`. An invoice earlier
38
+ * than the anchor is allowed: an invoice may be issued while charges still accrue.
39
+ * - Every emitted date is canonical bare ISO (`Temporal.PlainDate#toString()`), so an input
40
+ * annotation such as `[u-ca=iso8601]` does not reach the output, as `addDate` behaves.
41
+ * - Returns `null` when `dates` or `windows` is not an object, `anchorOn` or a given optional
42
+ * date is not a valid ISO date, a window is missing or not a safe integer of at least `0`, a
43
+ * request exists without an invoice or before it, `agreedResolutionOn` is before the request,
44
+ * or a deadline would leave Temporal's range.
45
+ *
46
+ * @param dates The anchor date, and the invoice and request dates once they exist
47
+ * @param windows The three calendar-day windows, none defaulted, and an agreed resolution date
48
+ * @returns { invoiceDeadline, issuedByDeadline, disputeDeadline, requestedByDeadline, resolutionDeadline }, or null on invalid input
49
+ *
50
+ * @example billingTimeline({ anchorOn: "2026-03-01" }, { issueDays: 30, disputeDays: 30, resolutionDays: 30 }) // { invoiceDeadline: "2026-03-31", issuedByDeadline: null, disputeDeadline: null, requestedByDeadline: null, resolutionDeadline: null } (no invoice yet: a forecast)
51
+ * @example billingTimeline({ anchorOn: "2026-03-01", invoiceIssuedOn: "2026-03-31" }, { issueDays: 30, disputeDays: 30, resolutionDays: 30 }) // { invoiceDeadline: "2026-03-31", issuedByDeadline: true, disputeDeadline: "2026-04-30", requestedByDeadline: null, resolutionDeadline: null } (day 30 is the last day by the deadline)
52
+ * @example billingTimeline({ anchorOn: "2026-03-01", invoiceIssuedOn: "2026-04-01" }, { issueDays: 30, disputeDays: 30, resolutionDays: 30 }) // { invoiceDeadline: "2026-03-31", issuedByDeadline: false, disputeDeadline: "2026-05-01", requestedByDeadline: null, resolutionDeadline: null } (day 31)
53
+ * @example billingTimeline({ anchorOn: "2026-03-01", invoiceIssuedOn: "2026-03-20", requestReceivedOn: "2026-04-19" }, { issueDays: 30, disputeDays: 30, resolutionDays: 30 }) // { invoiceDeadline: "2026-03-31", issuedByDeadline: true, disputeDeadline: "2026-04-19", requestedByDeadline: true, resolutionDeadline: "2026-05-19" }
54
+ * @example billingTimeline({ anchorOn: "2026-03-01", invoiceIssuedOn: "2026-03-20", requestReceivedOn: "2026-04-20" }, { issueDays: 30, disputeDays: 30, resolutionDays: 30, agreedResolutionOn: "2026-06-01" }) // { invoiceDeadline: "2026-03-31", issuedByDeadline: true, disputeDeadline: "2026-04-19", requestedByDeadline: false, resolutionDeadline: "2026-06-01" } (an agreed date replaces the computed one)
55
+ * @example billingTimeline({ anchorOn: "2026-03-10", invoiceIssuedOn: "2026-04-05" }, { issueDays: 30, disputeDays: 30, resolutionDays: 30 }) // { invoiceDeadline: "2026-04-09", issuedByDeadline: true, disputeDeadline: "2026-05-05", requestedByDeadline: null, resolutionDeadline: null } (a re-bill anchored on the invoice it received, not on the charge)
56
+ * @example billingTimeline({ anchorOn: "2026-03-01", invoiceIssuedOn: "2026-03-05", requestReceivedOn: "2026-03-18" }, { issueDays: 14, disputeDays: 14, resolutionDays: 45 }) // { invoiceDeadline: "2026-03-15", issuedByDeadline: true, disputeDeadline: "2026-03-19", requestedByDeadline: true, resolutionDeadline: "2026-05-02" } (a service contract's own windows)
57
+ * @example billingTimeline({ anchorOn: "2028-01-30" }, { issueDays: 30, disputeDays: 30, resolutionDays: 30 }) // { invoiceDeadline: "2028-02-29", issuedByDeadline: null, disputeDeadline: null, requestedByDeadline: null, resolutionDeadline: null } (calendar days across a leap day)
58
+ * @example billingTimeline({ anchorOn: "2026-03-01", invoiceIssuedOn: "2026-03-31" }, { disputeDays: 30, resolutionDays: 30 }) // null (issueDays has no default)
59
+ * @example billingTimeline({ anchorOn: "2026-03-01", requestReceivedOn: "2026-04-19" }, { issueDays: 30, disputeDays: 30, resolutionDays: 30 }) // null (a request cannot precede the invoice it disputes)
60
+ */
61
+ export function billingTimeline(dates, windows) {
62
+ try {
63
+ return layOutDeadlines(dates, windows);
64
+ }
65
+ catch {
66
+ // Never throws (Core Rule 3): a hostile
67
+ // argument is invalid input, not an exception.
68
+ return null;
69
+ }
70
+ }
71
+ /** A window is a whole number of calendar days, zero or more. */
72
+ function isWindow(value) {
73
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
74
+ }
75
+ /** An optional date is absent (`undefined`) or a valid ISO date; anything else is invalid. */
76
+ function optionalDate(value) {
77
+ if (value === undefined) {
78
+ return undefined;
79
+ }
80
+ return typeof value === "string" && isValidDate(value) ? value : null;
81
+ }
82
+ /** `date + days` on the ISO calendar, canonical. Throws `RangeError` past Temporal's range. */
83
+ function plusDays(date, days) {
84
+ return Temporal.PlainDate.from(date).add({ days }).toString();
85
+ }
86
+ /** Whether `date` is on or before `deadline`. */
87
+ function byDeadline(date, deadline) {
88
+ return (Temporal.PlainDate.compare(Temporal.PlainDate.from(date), Temporal.PlainDate.from(deadline)) <= 0);
89
+ }
90
+ /** The dates, each a valid ISO date, with no request before its invoice; `null` otherwise. */
91
+ function readDates(dates) {
92
+ const { anchorOn } = dates;
93
+ if (typeof anchorOn !== "string" || !isValidDate(anchorOn)) {
94
+ return null;
95
+ }
96
+ const invoiceIssuedOn = optionalDate(dates.invoiceIssuedOn);
97
+ const requestReceivedOn = optionalDate(dates.requestReceivedOn);
98
+ if (invoiceIssuedOn === null || requestReceivedOn === null) {
99
+ return null;
100
+ }
101
+ // A request cannot precede the invoice it disputes.
102
+ if (requestReceivedOn !== undefined &&
103
+ (invoiceIssuedOn === undefined ||
104
+ !byDeadline(invoiceIssuedOn, requestReceivedOn))) {
105
+ return null;
106
+ }
107
+ return { anchorOn, invoiceIssuedOn, requestReceivedOn };
108
+ }
109
+ /** The three windows, each present and valid, and the agreed date if given; `null` otherwise. */
110
+ function readWindows(windows) {
111
+ const { issueDays, disputeDays, resolutionDays } = windows;
112
+ if (!isWindow(issueDays) ||
113
+ !isWindow(disputeDays) ||
114
+ !isWindow(resolutionDays)) {
115
+ return null;
116
+ }
117
+ const agreedResolutionOn = optionalDate(windows.agreedResolutionOn);
118
+ if (agreedResolutionOn === null) {
119
+ return null;
120
+ }
121
+ return { issueDays, disputeDays, resolutionDays, agreedResolutionOn };
122
+ }
123
+ /** The agreed date when given, else `requestReceivedOn + resolutionDays`; `null` with no request. */
124
+ function resolutionDeadline(requestReceivedOn, windows) {
125
+ if (requestReceivedOn === undefined) {
126
+ return null;
127
+ }
128
+ return windows.agreedResolutionOn === undefined
129
+ ? plusDays(requestReceivedOn, windows.resolutionDays)
130
+ : Temporal.PlainDate.from(windows.agreedResolutionOn).toString();
131
+ }
132
+ /** Whether `date` is on or before `deadline`; `null` until both exist. */
133
+ function onOrBefore(date, deadline) {
134
+ return date === undefined || deadline === null
135
+ ? null
136
+ : byDeadline(date, deadline);
137
+ }
138
+ /** An agreed resolution date cannot precede the request it resolves. */
139
+ function agreedAfterRequest(requestReceivedOn, agreedResolutionOn) {
140
+ return (requestReceivedOn === undefined ||
141
+ agreedResolutionOn === undefined ||
142
+ byDeadline(requestReceivedOn, agreedResolutionOn));
143
+ }
144
+ /** `billingTimeline` without the guard; every read of its arguments happens here. */
145
+ function layOutDeadlines(dates, windows) {
146
+ if (!isObject(dates) || !isObject(windows)) {
147
+ return null;
148
+ }
149
+ const read = readDates(dates);
150
+ const counts = readWindows(windows);
151
+ if (read === null ||
152
+ counts === null ||
153
+ !agreedAfterRequest(read.requestReceivedOn, counts.agreedResolutionOn)) {
154
+ return null;
155
+ }
156
+ const { anchorOn, invoiceIssuedOn, requestReceivedOn } = read;
157
+ const invoiceDeadline = plusDays(anchorOn, counts.issueDays);
158
+ const disputeDeadline = invoiceIssuedOn === undefined
159
+ ? null
160
+ : plusDays(invoiceIssuedOn, counts.disputeDays);
161
+ return {
162
+ invoiceDeadline,
163
+ issuedByDeadline: onOrBefore(invoiceIssuedOn, invoiceDeadline),
164
+ disputeDeadline,
165
+ requestedByDeadline: onOrBefore(requestReceivedOn, disputeDeadline),
166
+ resolutionDeadline: resolutionDeadline(requestReceivedOn, counts),
167
+ };
168
+ }
@@ -0,0 +1,100 @@
1
+ import type { FreeTimeBasis, FreeTimeOptions } from "../../types/index.js";
2
+ /** A band of chargeable-day ordinals and how many of the charged days fell in it. */
3
+ export interface TierBand {
4
+ /** The first chargeable-day ordinal of the band, from 1. */
5
+ from: number;
6
+ /** The last ordinal of the band, or `null` for the open final band. */
7
+ to: number | null;
8
+ /** The number of charged days that fell in the band. */
9
+ days: number;
10
+ }
11
+ /** What `chargeableDays` returns: the day count an invoice bills, and the dates that back it. */
12
+ export interface FreeTimeCharges {
13
+ /** The number of free days the dwell touched, at most the tariff's `freeDays`. */
14
+ freeDaysUsed: number;
15
+ /** The number of counted days on or after `expiresAt` the dwell touched. */
16
+ chargeableDays: number;
17
+ /** The instant free time ended, as a UTC instant, as `freeTimeExpiry` reports it. */
18
+ expiresAt: string;
19
+ /**
20
+ * The local dates charged, ascending. Carriers' day-numbered tariff grids and progressive tiers
21
+ * are applied to this list, and its entries are the dates an itemised invoice can list.
22
+ */
23
+ chargedDates: string[];
24
+ /** The charged days split into the `tiers` bands; one open band when no tiers were given. */
25
+ byTier: TierBand[];
26
+ }
27
+ /** `FreeTimeOptions` plus how charged days are counted, and the optional tier boundaries. */
28
+ export type FreeTimeChargeOptions = FreeTimeOptions & {
29
+ /**
30
+ * How days after expiry are charged: `"calendar"` charges every local day, `"working"` only the
31
+ * working days of `calendar`. No default; see `chargeableDays`.
32
+ */
33
+ chargeBasis: FreeTimeBasis;
34
+ /**
35
+ * The last chargeable-day ordinal of each band, as strictly ascending positive whole numbers:
36
+ * `[5, 10]` is days 1–5, 6–10 and 11 onward. They are day bands, not rates. Every band is
37
+ * returned, an empty one with `days: 0`, and the last is always open.
38
+ *
39
+ * @defaultValue None. `byTier` is the single open band `{ from: 1, to: null }`.
40
+ */
41
+ tiers?: number[];
42
+ };
43
+ /**
44
+ * Count the days a container is charged for between the start of its clock and its exit,
45
+ * and list the dates behind the count.
46
+ *
47
+ * Lays out free time with the same walk as `freeTimeExpiry`, then counts the days on or after
48
+ * the expiry that the half-open dwell `[clockStart, clockEnd)` touched. The result is the
49
+ * auditable form of a demurrage or detention charge: `chargedDates` lists the days behind the
50
+ * count, which is the list a day-numbered tariff grid is applied to, and the dates an itemised
51
+ * invoice can list. No regulation or industry standard fixes how the days are counted; every term
52
+ * below is the tariff's. GMT computes days, never money: `byTier` says how many days fell in each
53
+ * band so the caller can apply its rates.
54
+ *
55
+ * - **Half-open at the exit.** A day is charged when it started before `clockEnd`, so a
56
+ * gate-out at exactly `expiresAt` is `0` chargeable days and one nanosecond later is `1`. A
57
+ * zero-length dwell touches the day it sits on, as `dwellTime` counts. On the calendar basis
58
+ * with `firstDay: "eventDay"`, `freeDaysUsed + chargeableDays` equals `dwellTime(...).calendarDays`,
59
+ * with one exception: a fall-back that re-enters the day before the event day (`America/Goose_Bay`,
60
+ * 00:01 on 7 November 2010 back into the 6th) is a date `dwellTime` counts as touched, and a
61
+ * tariff never counts a date before the event day.
62
+ * - **The free-time terms are `freeTimeExpiry`'s**: `basis`, `timeZone`, `firstDay` and
63
+ * `calendar` mean the same, and `firstDay` has no default.
64
+ * - **`chargeBasis` says how days after expiry are charged, and has no default.** Many
65
+ * tariffs count free time and charges alike in calendar days. Where a tariff grants free time in
66
+ * working days, the days after it are mostly charged as calendar days, weekends and holidays
67
+ * included (Hapag-Lloyd's tables: "Rate per Calendar day"; ACL: "Once free time expires ...
68
+ * charged on calendar days"): `basis: "working", chargeBasis: "calendar"`. Some tariffs charge
69
+ * working days only, for free time and charges alike, so neither counts a day the gate is
70
+ * closed or a holiday: both `"working"`.
71
+ * Either `"working"` needs `calendar`. The two differ by every closed day after expiry, so
72
+ * neither is assumed.
73
+ * - **`freeDays` may be `0`** for a tariff with no free time: `expiresAt` is the start of day one,
74
+ * the first day counted on `basis` (under `"nextDay"`, the first after the event day), and days
75
+ * before it are neither free nor charged.
76
+ * - Returns `null` when either instant is invalid, `clockEnd` is before `clockStart` (an
77
+ * inverted dwell is a data error), `freeDays` is not a whole number of at least `0`, the
78
+ * options fail as they do for `freeTimeExpiry`, `tiers` has a hole, an unsafe integer or does not ascend, or the walk would pass
79
+ * 10,000 local days.
80
+ *
81
+ * @param clockStart ISO 8601 instant string of the event that starts the clock
82
+ * @param clockEnd ISO 8601 instant string of the event that stops it (gate-out or empty return)
83
+ * @param freeDays whole number of free days the tariff allows, 0 or more
84
+ * @param options The tariff's counting terms for free time and for charged days, and the tier bands
85
+ * @returns the free days used, the chargeable days, the expiry, the charged dates and the days per tier band, or null on invalid input
86
+ *
87
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-17T04:00:00Z", 3, { basis: "calendar", chargeBasis: "calendar", timeZone: "America/New_York", firstDay: "eventDay" }) // { freeDaysUsed: 3, chargeableDays: 0, expiresAt: "2024-06-17T04:00:00Z", chargedDates: [], byTier: [{ from: 1, to: null, days: 0 }] } (gate-out exactly at expiry is free)
88
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-17T04:00:01Z", 3, { basis: "calendar", chargeBasis: "calendar", timeZone: "America/New_York", firstDay: "eventDay" }) // { freeDaysUsed: 3, chargeableDays: 1, expiresAt: "2024-06-17T04:00:00Z", chargedDates: ["2024-06-17"], byTier: [{ from: 1, to: null, days: 1 }] } (one second later is a charged day)
89
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-17T04:00:01Z", 3, { basis: "calendar", chargeBasis: "calendar", timeZone: "America/New_York", firstDay: "nextDay" }) // { freeDaysUsed: 3, chargeableDays: 0, expiresAt: "2024-06-18T04:00:00Z", chargedDates: [], byTier: [{ from: 1, to: null, days: 0 }] } (the other start-day convention: still free)
90
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-28T15:00:00Z", 3, { basis: "calendar", chargeBasis: "calendar", timeZone: "America/New_York", firstDay: "eventDay", tiers: [5, 10] }) // { freeDaysUsed: 3, chargeableDays: 12, expiresAt: "2024-06-17T04:00:00Z", chargedDates: ["2024-06-17", "2024-06-18", "2024-06-19", "2024-06-20", "2024-06-21", "2024-06-22", "2024-06-23", "2024-06-24", "2024-06-25", "2024-06-26", "2024-06-27", "2024-06-28"], byTier: [{ from: 1, to: 5, days: 5 }, { from: 6, to: 10, days: 5 }, { from: 11, to: null, days: 2 }] }
91
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-24T15:00:00Z", 3, { basis: "working", chargeBasis: "calendar", timeZone: "America/New_York", firstDay: "eventDay", calendar: { weekend: [6, 7], holidays: ["2024-06-19"], timeZone: "America/New_York" } }) // { freeDaysUsed: 3, chargeableDays: 6, expiresAt: "2024-06-19T04:00:00Z", chargedDates: ["2024-06-19", "2024-06-20", "2024-06-21", "2024-06-22", "2024-06-23", "2024-06-24"], byTier: [{ from: 1, to: null, days: 6 }] } (free days in working days, every calendar day after expiry charged)
92
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-24T15:00:00Z", 3, { basis: "working", chargeBasis: "working", timeZone: "America/New_York", firstDay: "eventDay", calendar: { weekend: [6, 7], holidays: ["2024-06-19"], timeZone: "America/New_York" } }) // { freeDaysUsed: 3, chargeableDays: 3, expiresAt: "2024-06-19T04:00:00Z", chargedDates: ["2024-06-20", "2024-06-21", "2024-06-24"], byTier: [{ from: 1, to: null, days: 3 }] } (working days throughout: closed days after expiry are not charged)
93
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-15T15:00:00Z", 3, { basis: "calendar", chargeBasis: "calendar", timeZone: "America/New_York", firstDay: "eventDay" }) // { freeDaysUsed: 2, chargeableDays: 0, expiresAt: "2024-06-17T04:00:00Z", chargedDates: [], byTier: [{ from: 1, to: null, days: 0 }] } (out on the second free day)
94
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-16T15:00:00Z", 0, { basis: "calendar", chargeBasis: "calendar", timeZone: "America/New_York", firstDay: "eventDay" }) // { freeDaysUsed: 0, chargeableDays: 3, expiresAt: "2024-06-14T04:00:00Z", chargedDates: ["2024-06-14", "2024-06-15", "2024-06-16"], byTier: [{ from: 1, to: null, days: 3 }] } (no free time: every day is charged)
95
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-28T15:00:00Z", 3, { basis: "calendar", chargeBasis: "calendar", timeZone: "America/New_York", firstDay: "eventDay", tiers: [10, 5] }) // null (tiers must ascend)
96
+ * @example chargeableDays("2024-06-17T04:00:01Z", "2024-06-14T19:00:00Z", 3, { basis: "calendar", chargeBasis: "calendar", timeZone: "America/New_York", firstDay: "eventDay" }) // null (exit before the clock started)
97
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-17T04:00:01Z", 3, { basis: "calendar", chargeBasis: "calendar", timeZone: "America/New_York" }) // null (firstDay has no default)
98
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-17T04:00:01Z", 3, { basis: "calendar", timeZone: "America/New_York", firstDay: "eventDay" }) // null (chargeBasis has no default)
99
+ */
100
+ export declare function chargeableDays(clockStart: string, clockEnd: string, freeDays: number, options: FreeTimeChargeOptions): FreeTimeCharges | null;
@@ -0,0 +1,96 @@
1
+ import { Temporal } from "@js-temporal/polyfill";
2
+ import { bandsByTier, instantFrom, parseFreeDays, parseFreeTimeTerms, parseTiers, walkFreeTime, } from "../../internal/index.js";
3
+ import { isValidInstant } from "../../precision/validate/isValidInstant.js";
4
+ /**
5
+ * Count the days a container is charged for between the start of its clock and its exit,
6
+ * and list the dates behind the count.
7
+ *
8
+ * Lays out free time with the same walk as `freeTimeExpiry`, then counts the days on or after
9
+ * the expiry that the half-open dwell `[clockStart, clockEnd)` touched. The result is the
10
+ * auditable form of a demurrage or detention charge: `chargedDates` lists the days behind the
11
+ * count, which is the list a day-numbered tariff grid is applied to, and the dates an itemised
12
+ * invoice can list. No regulation or industry standard fixes how the days are counted; every term
13
+ * below is the tariff's. GMT computes days, never money: `byTier` says how many days fell in each
14
+ * band so the caller can apply its rates.
15
+ *
16
+ * - **Half-open at the exit.** A day is charged when it started before `clockEnd`, so a
17
+ * gate-out at exactly `expiresAt` is `0` chargeable days and one nanosecond later is `1`. A
18
+ * zero-length dwell touches the day it sits on, as `dwellTime` counts. On the calendar basis
19
+ * with `firstDay: "eventDay"`, `freeDaysUsed + chargeableDays` equals `dwellTime(...).calendarDays`,
20
+ * with one exception: a fall-back that re-enters the day before the event day (`America/Goose_Bay`,
21
+ * 00:01 on 7 November 2010 back into the 6th) is a date `dwellTime` counts as touched, and a
22
+ * tariff never counts a date before the event day.
23
+ * - **The free-time terms are `freeTimeExpiry`'s**: `basis`, `timeZone`, `firstDay` and
24
+ * `calendar` mean the same, and `firstDay` has no default.
25
+ * - **`chargeBasis` says how days after expiry are charged, and has no default.** Many
26
+ * tariffs count free time and charges alike in calendar days. Where a tariff grants free time in
27
+ * working days, the days after it are mostly charged as calendar days, weekends and holidays
28
+ * included (Hapag-Lloyd's tables: "Rate per Calendar day"; ACL: "Once free time expires ...
29
+ * charged on calendar days"): `basis: "working", chargeBasis: "calendar"`. Some tariffs charge
30
+ * working days only, for free time and charges alike, so neither counts a day the gate is
31
+ * closed or a holiday: both `"working"`.
32
+ * Either `"working"` needs `calendar`. The two differ by every closed day after expiry, so
33
+ * neither is assumed.
34
+ * - **`freeDays` may be `0`** for a tariff with no free time: `expiresAt` is the start of day one,
35
+ * the first day counted on `basis` (under `"nextDay"`, the first after the event day), and days
36
+ * before it are neither free nor charged.
37
+ * - Returns `null` when either instant is invalid, `clockEnd` is before `clockStart` (an
38
+ * inverted dwell is a data error), `freeDays` is not a whole number of at least `0`, the
39
+ * options fail as they do for `freeTimeExpiry`, `tiers` has a hole, an unsafe integer or does not ascend, or the walk would pass
40
+ * 10,000 local days.
41
+ *
42
+ * @param clockStart ISO 8601 instant string of the event that starts the clock
43
+ * @param clockEnd ISO 8601 instant string of the event that stops it (gate-out or empty return)
44
+ * @param freeDays whole number of free days the tariff allows, 0 or more
45
+ * @param options The tariff's counting terms for free time and for charged days, and the tier bands
46
+ * @returns the free days used, the chargeable days, the expiry, the charged dates and the days per tier band, or null on invalid input
47
+ *
48
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-17T04:00:00Z", 3, { basis: "calendar", chargeBasis: "calendar", timeZone: "America/New_York", firstDay: "eventDay" }) // { freeDaysUsed: 3, chargeableDays: 0, expiresAt: "2024-06-17T04:00:00Z", chargedDates: [], byTier: [{ from: 1, to: null, days: 0 }] } (gate-out exactly at expiry is free)
49
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-17T04:00:01Z", 3, { basis: "calendar", chargeBasis: "calendar", timeZone: "America/New_York", firstDay: "eventDay" }) // { freeDaysUsed: 3, chargeableDays: 1, expiresAt: "2024-06-17T04:00:00Z", chargedDates: ["2024-06-17"], byTier: [{ from: 1, to: null, days: 1 }] } (one second later is a charged day)
50
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-17T04:00:01Z", 3, { basis: "calendar", chargeBasis: "calendar", timeZone: "America/New_York", firstDay: "nextDay" }) // { freeDaysUsed: 3, chargeableDays: 0, expiresAt: "2024-06-18T04:00:00Z", chargedDates: [], byTier: [{ from: 1, to: null, days: 0 }] } (the other start-day convention: still free)
51
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-28T15:00:00Z", 3, { basis: "calendar", chargeBasis: "calendar", timeZone: "America/New_York", firstDay: "eventDay", tiers: [5, 10] }) // { freeDaysUsed: 3, chargeableDays: 12, expiresAt: "2024-06-17T04:00:00Z", chargedDates: ["2024-06-17", "2024-06-18", "2024-06-19", "2024-06-20", "2024-06-21", "2024-06-22", "2024-06-23", "2024-06-24", "2024-06-25", "2024-06-26", "2024-06-27", "2024-06-28"], byTier: [{ from: 1, to: 5, days: 5 }, { from: 6, to: 10, days: 5 }, { from: 11, to: null, days: 2 }] }
52
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-24T15:00:00Z", 3, { basis: "working", chargeBasis: "calendar", timeZone: "America/New_York", firstDay: "eventDay", calendar: { weekend: [6, 7], holidays: ["2024-06-19"], timeZone: "America/New_York" } }) // { freeDaysUsed: 3, chargeableDays: 6, expiresAt: "2024-06-19T04:00:00Z", chargedDates: ["2024-06-19", "2024-06-20", "2024-06-21", "2024-06-22", "2024-06-23", "2024-06-24"], byTier: [{ from: 1, to: null, days: 6 }] } (free days in working days, every calendar day after expiry charged)
53
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-24T15:00:00Z", 3, { basis: "working", chargeBasis: "working", timeZone: "America/New_York", firstDay: "eventDay", calendar: { weekend: [6, 7], holidays: ["2024-06-19"], timeZone: "America/New_York" } }) // { freeDaysUsed: 3, chargeableDays: 3, expiresAt: "2024-06-19T04:00:00Z", chargedDates: ["2024-06-20", "2024-06-21", "2024-06-24"], byTier: [{ from: 1, to: null, days: 3 }] } (working days throughout: closed days after expiry are not charged)
54
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-15T15:00:00Z", 3, { basis: "calendar", chargeBasis: "calendar", timeZone: "America/New_York", firstDay: "eventDay" }) // { freeDaysUsed: 2, chargeableDays: 0, expiresAt: "2024-06-17T04:00:00Z", chargedDates: [], byTier: [{ from: 1, to: null, days: 0 }] } (out on the second free day)
55
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-16T15:00:00Z", 0, { basis: "calendar", chargeBasis: "calendar", timeZone: "America/New_York", firstDay: "eventDay" }) // { freeDaysUsed: 0, chargeableDays: 3, expiresAt: "2024-06-14T04:00:00Z", chargedDates: ["2024-06-14", "2024-06-15", "2024-06-16"], byTier: [{ from: 1, to: null, days: 3 }] } (no free time: every day is charged)
56
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-28T15:00:00Z", 3, { basis: "calendar", chargeBasis: "calendar", timeZone: "America/New_York", firstDay: "eventDay", tiers: [10, 5] }) // null (tiers must ascend)
57
+ * @example chargeableDays("2024-06-17T04:00:01Z", "2024-06-14T19:00:00Z", 3, { basis: "calendar", chargeBasis: "calendar", timeZone: "America/New_York", firstDay: "eventDay" }) // null (exit before the clock started)
58
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-17T04:00:01Z", 3, { basis: "calendar", chargeBasis: "calendar", timeZone: "America/New_York" }) // null (firstDay has no default)
59
+ * @example chargeableDays("2024-06-14T19:00:00Z", "2024-06-17T04:00:01Z", 3, { basis: "calendar", timeZone: "America/New_York", firstDay: "eventDay" }) // null (chargeBasis has no default)
60
+ */
61
+ export function chargeableDays(clockStart, clockEnd, freeDays, options) {
62
+ try {
63
+ const terms = parseFreeTimeTerms(options, true);
64
+ const allowed = parseFreeDays(freeDays, 0);
65
+ // Read after the terms, so a non-object `options` is never read from.
66
+ const tiers = terms === null ? null : parseTiers(options.tiers);
67
+ if (!isValidInstant(clockStart) ||
68
+ !isValidInstant(clockEnd) ||
69
+ terms === null ||
70
+ allowed === null ||
71
+ tiers === null) {
72
+ return null;
73
+ }
74
+ const start = instantFrom(clockStart).toZonedDateTimeISO(terms.timeZone);
75
+ const end = instantFrom(clockEnd).toZonedDateTimeISO(terms.timeZone);
76
+ if (Temporal.ZonedDateTime.compare(start, end) > 0) {
77
+ return null;
78
+ }
79
+ const ledger = walkFreeTime(start, allowed, terms, end);
80
+ if (ledger === null) {
81
+ return null;
82
+ }
83
+ return {
84
+ freeDaysUsed: ledger.used,
85
+ chargeableDays: ledger.charged.length,
86
+ expiresAt: ledger.expiresAt.toInstant().toString(),
87
+ chargedDates: ledger.charged.map((day) => day.date),
88
+ byTier: bandsByTier(tiers, ledger.charged.length),
89
+ };
90
+ }
91
+ catch {
92
+ // Never throws (Core Rule 3): a hostile
93
+ // argument is invalid input, not an exception.
94
+ return null;
95
+ }
96
+ }