@northguild/gmt 1.17.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 (638) hide show
  1. package/README.md +462 -22
  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/instant/convert/classifyLocal.d.ts +1 -1
  43. package/dist/instant/convert/classifyLocal.js +1 -1
  44. package/dist/instant/convert/fromOffsetInstant.d.ts +3 -1
  45. package/dist/instant/convert/fromOffsetInstant.js +3 -1
  46. package/dist/instant/convert/resolveLocal.d.ts +12 -7
  47. package/dist/instant/convert/resolveLocal.js +6 -10
  48. package/dist/instant/convert/toOffsetInstant.d.ts +22 -9
  49. package/dist/instant/convert/toOffsetInstant.js +10 -3
  50. package/dist/intermodal/calculate/billingTimeline.d.ts +31 -11
  51. package/dist/intermodal/calculate/billingTimeline.js +2 -2
  52. package/dist/intermodal/calculate/chargeableDays.d.ts +13 -11
  53. package/dist/intermodal/calculate/chargeableDays.js +4 -9
  54. package/dist/intermodal/calculate/demurrageClock.d.ts +16 -7
  55. package/dist/intermodal/calculate/demurrageClock.js +7 -7
  56. package/dist/intermodal/calculate/freeTimeExpiry.d.ts +5 -4
  57. package/dist/intermodal/calculate/freeTimeExpiry.js +6 -6
  58. package/dist/internal/businessCalendar.d.ts +5 -0
  59. package/dist/internal/businessCalendar.js +5 -1
  60. package/dist/internal/cycleFieldValue.d.ts +6 -4
  61. package/dist/internal/cycleFieldValue.js +6 -4
  62. package/dist/internal/daylightTime.d.ts +33 -0
  63. package/dist/internal/daylightTime.js +164 -0
  64. package/dist/internal/durationUntilString.js +4 -3
  65. package/dist/internal/englishCalendarNames.js +1 -2
  66. package/dist/internal/epochNanoseconds.d.ts +2 -0
  67. package/dist/internal/epochNanoseconds.js +2 -0
  68. package/dist/internal/exactDuration.d.ts +37 -0
  69. package/dist/internal/exactDuration.js +64 -0
  70. package/dist/internal/exactMoment.d.ts +72 -0
  71. package/dist/internal/exactMoment.js +114 -0
  72. package/dist/internal/fiscalCalendar.d.ts +4 -3
  73. package/dist/internal/fiscalCalendar.js +4 -3
  74. package/dist/internal/formatCalendarDays.d.ts +2 -2
  75. package/dist/internal/formatRelativeDuration.d.ts +21 -1
  76. package/dist/internal/formatRelativeDuration.js +47 -7
  77. package/dist/internal/index.d.ts +9 -4
  78. package/dist/internal/index.js +9 -4
  79. package/dist/internal/instantFormatOptions.js +2 -1
  80. package/dist/internal/instantNanoseconds.d.ts +75 -9
  81. package/dist/internal/instantNanoseconds.js +192 -11
  82. package/dist/internal/joinDateTimeConnector.d.ts +1 -1
  83. package/dist/internal/monthGridWeekRow.d.ts +2 -1
  84. package/dist/internal/monthGridWeekRow.js +2 -1
  85. package/dist/internal/normalizeTimeZone.d.ts +2 -2
  86. package/dist/internal/normalizeTimeZone.js +2 -2
  87. package/dist/internal/operatingSchedule.d.ts +129 -0
  88. package/dist/internal/operatingSchedule.js +668 -0
  89. package/dist/internal/optionOrDefault.d.ts +18 -0
  90. package/dist/internal/optionOrDefault.js +20 -0
  91. package/dist/internal/patternToken.d.ts +2 -2
  92. package/dist/internal/patternToken.js +28 -13
  93. package/dist/internal/plainDateUntil.js +10 -6
  94. package/dist/internal/punctuality.d.ts +38 -0
  95. package/dist/internal/punctuality.js +59 -0
  96. package/dist/internal/readDateTimeFormatOptions.d.ts +30 -0
  97. package/dist/internal/readDateTimeFormatOptions.js +93 -0
  98. package/dist/internal/resolveDurationRelativeTo.d.ts +4 -0
  99. package/dist/internal/resolveDurationRelativeTo.js +11 -1
  100. package/dist/internal/resolveRelativeRounding.d.ts +17 -6
  101. package/dist/internal/resolveRelativeRounding.js +27 -7
  102. package/dist/internal/resolveRelativeUnit.d.ts +30 -0
  103. package/dist/internal/resolveRelativeUnit.js +40 -0
  104. package/dist/internal/splitStep.d.ts +24 -1
  105. package/dist/internal/splitStep.js +34 -2
  106. package/dist/internal/startOrEndOfZoned.js +2 -3
  107. package/dist/internal/temporalCompat/capabilities.d.ts +26 -0
  108. package/dist/internal/temporalCompat/capabilities.js +35 -3
  109. package/dist/internal/temporalCompat/fieldSearch.js +1 -1
  110. package/dist/internal/temporalCompat/index.d.ts +1 -1
  111. package/dist/internal/temporalCompat/index.js +1 -1
  112. package/dist/internal/temporalCompat/repros.d.ts +1 -1
  113. package/dist/internal/temporalCompat/repros.js +157 -0
  114. package/dist/internal/timestampEvents.d.ts +32 -0
  115. package/dist/internal/timestampEvents.js +76 -0
  116. package/dist/internal/utcZonedDateTime.d.ts +5 -2
  117. package/dist/internal/utcZonedDateTime.js +8 -5
  118. package/dist/internal/zonedBucket.js +8 -6
  119. package/dist/internal/zonedLocalDates.js +1 -1
  120. package/dist/internal/zonedTransitionSearch.d.ts +27 -0
  121. package/dist/internal/zonedTransitionSearch.js +218 -0
  122. package/dist/internal/zonedWallClock.d.ts +21 -7
  123. package/dist/internal/zonedWallClock.js +87 -18
  124. package/dist/internal/zonedWallClockOperations.d.ts +26 -13
  125. package/dist/internal/zonedWallClockOperations.js +87 -34
  126. package/dist/interval/validate/isValidInterval.d.ts +6 -3
  127. package/dist/interval/validate/isValidInterval.js +6 -3
  128. package/dist/plain/calculate/addDate.d.ts +11 -8
  129. package/dist/plain/calculate/addDate.js +5 -8
  130. package/dist/plain/calculate/addDateTime.d.ts +7 -4
  131. package/dist/plain/calculate/addDateTime.js +1 -4
  132. package/dist/plain/calculate/cycleDate.d.ts +16 -7
  133. package/dist/plain/calculate/cycleDate.js +3 -7
  134. package/dist/plain/calculate/cycleDateTime.d.ts +14 -4
  135. package/dist/plain/calculate/cycleDateTime.js +1 -4
  136. package/dist/plain/calculate/cycleTime.d.ts +10 -5
  137. package/dist/plain/calculate/cycleTime.js +3 -5
  138. package/dist/plain/calculate/diffDate.d.ts +1 -1
  139. package/dist/plain/calculate/diffDate.js +1 -1
  140. package/dist/plain/calculate/diffDateAsDuration.d.ts +1 -1
  141. package/dist/plain/calculate/diffDateAsDuration.js +1 -1
  142. package/dist/plain/calculate/diffDateTime.d.ts +1 -1
  143. package/dist/plain/calculate/diffDateTime.js +1 -1
  144. package/dist/plain/calculate/diffDateTimeAsDuration.d.ts +1 -1
  145. package/dist/plain/calculate/diffDateTimeAsDuration.js +1 -1
  146. package/dist/plain/calculate/diffTime.d.ts +1 -1
  147. package/dist/plain/calculate/diffTime.js +1 -1
  148. package/dist/plain/calculate/endOfDate.d.ts +8 -3
  149. package/dist/plain/calculate/endOfDate.js +1 -3
  150. package/dist/plain/calculate/endOfDateTime.d.ts +15 -5
  151. package/dist/plain/calculate/endOfDateTime.js +1 -5
  152. package/dist/plain/calculate/endOfTime.d.ts +8 -2
  153. package/dist/plain/calculate/endOfTime.js +1 -2
  154. package/dist/plain/calculate/getLocaleWeekYear.d.ts +16 -9
  155. package/dist/plain/calculate/getLocaleWeekYear.js +9 -9
  156. package/dist/plain/calculate/getWeekOfMonth.d.ts +7 -4
  157. package/dist/plain/calculate/getWeekOfMonth.js +7 -4
  158. package/dist/plain/calculate/getWeeksInLocaleWeekYear.d.ts +13 -6
  159. package/dist/plain/calculate/getWeeksInLocaleWeekYear.js +6 -6
  160. package/dist/plain/calculate/getWeeksInMonth.d.ts +5 -2
  161. package/dist/plain/calculate/getWeeksInMonth.js +5 -2
  162. package/dist/plain/calculate/nextWeekday.d.ts +7 -3
  163. package/dist/plain/calculate/nextWeekday.js +1 -3
  164. package/dist/plain/calculate/previousWeekday.d.ts +7 -3
  165. package/dist/plain/calculate/previousWeekday.js +1 -3
  166. package/dist/plain/calculate/roundDate.d.ts +20 -7
  167. package/dist/plain/calculate/roundDate.js +3 -10
  168. package/dist/plain/calculate/roundDateTime.d.ts +22 -8
  169. package/dist/plain/calculate/roundDateTime.js +3 -11
  170. package/dist/plain/calculate/roundTime.d.ts +20 -4
  171. package/dist/plain/calculate/roundTime.js +3 -7
  172. package/dist/plain/calculate/setDate.d.ts +7 -5
  173. package/dist/plain/calculate/setDate.js +1 -5
  174. package/dist/plain/calculate/setDateTime.d.ts +8 -5
  175. package/dist/plain/calculate/setDateTime.js +1 -5
  176. package/dist/plain/calculate/setTime.d.ts +10 -6
  177. package/dist/plain/calculate/setTime.js +4 -6
  178. package/dist/plain/calculate/startOfDate.d.ts +8 -2
  179. package/dist/plain/calculate/startOfDate.js +1 -2
  180. package/dist/plain/calculate/startOfDateTime.d.ts +15 -2
  181. package/dist/plain/calculate/startOfDateTime.js +1 -2
  182. package/dist/plain/calculate/startOfTime.d.ts +8 -1
  183. package/dist/plain/calculate/startOfTime.js +1 -1
  184. package/dist/plain/calculate/subtractDate.d.ts +7 -4
  185. package/dist/plain/calculate/subtractDate.js +1 -4
  186. package/dist/plain/calculate/subtractDateTime.d.ts +7 -4
  187. package/dist/plain/calculate/subtractDateTime.js +1 -4
  188. package/dist/plain/compare/areDateTimesEqualBy.d.ts +13 -5
  189. package/dist/plain/compare/areDateTimesEqualBy.js +6 -5
  190. package/dist/plain/compare/areDatesEqualBy.d.ts +15 -6
  191. package/dist/plain/compare/areDatesEqualBy.js +8 -6
  192. package/dist/plain/compare/isBetweenDate.d.ts +13 -2
  193. package/dist/plain/compare/isBetweenDate.js +4 -4
  194. package/dist/plain/compare/isBetweenDateTime.d.ts +13 -2
  195. package/dist/plain/compare/isBetweenDateTime.js +4 -4
  196. package/dist/plain/compare/isBetweenTime.d.ts +13 -2
  197. package/dist/plain/compare/isBetweenTime.js +4 -4
  198. package/dist/plain/compare/isRelativeDay.d.ts +1 -1
  199. package/dist/plain/compare/isRelativeDay.js +1 -1
  200. package/dist/plain/compare/isThisUnit.d.ts +1 -1
  201. package/dist/plain/compare/isThisUnit.js +1 -1
  202. package/dist/plain/format/formatCalendar.d.ts +21 -14
  203. package/dist/plain/format/formatCalendar.js +21 -16
  204. package/dist/plain/format/formatDate.js +5 -3
  205. package/dist/plain/format/formatDateRange.js +4 -2
  206. package/dist/plain/format/formatDateTime.js +4 -2
  207. package/dist/plain/format/formatDateTimeRange.js +4 -2
  208. package/dist/plain/format/formatDateTimeToParts.d.ts +15 -4
  209. package/dist/plain/format/formatDateTimeToParts.js +10 -6
  210. package/dist/plain/format/formatDateToParts.d.ts +13 -2
  211. package/dist/plain/format/formatDateToParts.js +8 -4
  212. package/dist/plain/format/formatRelativeDate.d.ts +16 -3
  213. package/dist/plain/format/formatRelativeDate.js +26 -15
  214. package/dist/plain/format/formatRelativeDateTime.d.ts +16 -3
  215. package/dist/plain/format/formatRelativeDateTime.js +8 -5
  216. package/dist/plain/format/formatRelativeTime.d.ts +16 -3
  217. package/dist/plain/format/formatRelativeTime.js +21 -13
  218. package/dist/plain/format/formatTime.js +4 -2
  219. package/dist/plain/interval/intervalDifferenceDate.d.ts +9 -0
  220. package/dist/plain/interval/intervalDifferenceDateTime.d.ts +9 -0
  221. package/dist/plain/interval/intervalDifferenceTime.d.ts +9 -0
  222. package/dist/plain/interval/intervalDivideEquallyDate.d.ts +19 -4
  223. package/dist/plain/interval/intervalDivideEquallyDate.js +3 -4
  224. package/dist/plain/interval/intervalDivideEquallyDateTime.d.ts +19 -4
  225. package/dist/plain/interval/intervalDivideEquallyDateTime.js +3 -4
  226. package/dist/plain/interval/intervalDivideEquallyTime.d.ts +19 -4
  227. package/dist/plain/interval/intervalDivideEquallyTime.js +3 -4
  228. package/dist/plain/interval/intervalFromDurationDate.d.ts +16 -3
  229. package/dist/plain/interval/intervalFromDurationDate.js +1 -3
  230. package/dist/plain/interval/intervalFromDurationDateTime.d.ts +16 -3
  231. package/dist/plain/interval/intervalFromDurationDateTime.js +1 -3
  232. package/dist/plain/interval/intervalFromDurationTime.d.ts +9 -0
  233. package/dist/plain/interval/intervalIntersectionDate.d.ts +9 -0
  234. package/dist/plain/interval/intervalIntersectionDateTime.d.ts +9 -0
  235. package/dist/plain/interval/intervalIntersectionTime.d.ts +9 -0
  236. package/dist/plain/interval/intervalSplitAtDate.d.ts +11 -0
  237. package/dist/plain/interval/intervalSplitAtDate.js +2 -0
  238. package/dist/plain/interval/intervalSplitAtDateTime.d.ts +11 -0
  239. package/dist/plain/interval/intervalSplitAtDateTime.js +2 -0
  240. package/dist/plain/interval/intervalSplitAtTime.d.ts +11 -0
  241. package/dist/plain/interval/intervalSplitAtTime.js +2 -0
  242. package/dist/plain/interval/intervalUnionDate.d.ts +9 -0
  243. package/dist/plain/interval/intervalUnionDateTime.d.ts +9 -0
  244. package/dist/plain/interval/intervalUnionTime.d.ts +9 -0
  245. package/dist/plain/interval/intervalXorAllDate.d.ts +9 -0
  246. package/dist/plain/interval/intervalXorAllDateTime.d.ts +9 -0
  247. package/dist/plain/interval/intervalXorAllTime.d.ts +9 -0
  248. package/dist/plain/interval/intervalXorDate.d.ts +9 -0
  249. package/dist/plain/interval/intervalXorDateTime.d.ts +9 -0
  250. package/dist/plain/interval/intervalXorTime.d.ts +9 -0
  251. package/dist/plain/interval/mergeIntervalsDate.d.ts +9 -0
  252. package/dist/plain/interval/mergeIntervalsDateTime.d.ts +9 -0
  253. package/dist/plain/interval/mergeIntervalsTime.d.ts +9 -0
  254. package/dist/plain/interval/splitIntervalByUnitDate.d.ts +23 -7
  255. package/dist/plain/interval/splitIntervalByUnitDate.js +7 -7
  256. package/dist/plain/interval/splitIntervalByUnitDateTime.d.ts +22 -6
  257. package/dist/plain/interval/splitIntervalByUnitDateTime.js +6 -6
  258. package/dist/plain/interval/splitIntervalByUnitTime.d.ts +17 -4
  259. package/dist/plain/interval/splitIntervalByUnitTime.js +1 -4
  260. package/dist/plain/map/mapDatesInRange.d.ts +8 -4
  261. package/dist/plain/map/mapDatesInRange.js +1 -4
  262. package/dist/plain/parse/parseDateTimeWithPattern.d.ts +10 -7
  263. package/dist/plain/parse/parseDateTimeWithPattern.js +10 -7
  264. package/dist/plain/parse/parseDateWithPattern.d.ts +10 -7
  265. package/dist/plain/parse/parseDateWithPattern.js +10 -7
  266. package/dist/plain/parse/parseTimeWithPattern.d.ts +10 -7
  267. package/dist/plain/parse/parseTimeWithPattern.js +10 -7
  268. package/dist/plain/parse/parseUnitFromDate.d.ts +11 -3
  269. package/dist/plain/parse/parseUnitFromDate.js +3 -3
  270. package/dist/plain/parse/parseUnitFromDateTime.d.ts +11 -3
  271. package/dist/plain/parse/parseUnitFromDateTime.js +3 -3
  272. package/dist/plain/parse/parseWeekFromDate.d.ts +10 -6
  273. package/dist/plain/parse/parseWeekFromDate.js +2 -6
  274. package/dist/plain/parse/parseWeekFromDateTime.d.ts +10 -6
  275. package/dist/plain/parse/parseWeekFromDateTime.js +2 -6
  276. package/dist/plain/validate/isValidDateRange.d.ts +19 -4
  277. package/dist/plain/validate/isValidDateRange.js +1 -4
  278. package/dist/plain/validate/isValidDateTimeRange.d.ts +20 -5
  279. package/dist/plain/validate/isValidDateTimeRange.js +2 -5
  280. package/dist/plain/validate/isValidTimeRange.d.ts +20 -5
  281. package/dist/plain/validate/isValidTimeRange.js +2 -5
  282. package/dist/precision/convert/fromExcelSerial.d.ts +10 -4
  283. package/dist/precision/convert/fromExcelSerial.js +4 -5
  284. package/dist/precision/convert/fromNanoseconds.d.ts +1 -1
  285. package/dist/precision/convert/fromNanoseconds.js +1 -1
  286. package/dist/precision/convert/toExcelSerial.d.ts +9 -3
  287. package/dist/precision/convert/toExcelSerial.js +3 -4
  288. package/dist/precision/convert/toNanoseconds.d.ts +11 -6
  289. package/dist/precision/convert/toNanoseconds.js +11 -6
  290. package/dist/precision/validate/isValidInstant.d.ts +12 -3
  291. package/dist/precision/validate/isValidInstant.js +12 -3
  292. package/dist/span/calculate/spanMs.d.ts +10 -4
  293. package/dist/span/calculate/spanMs.js +10 -4
  294. package/dist/span/calculate/spanNs.d.ts +10 -4
  295. package/dist/span/calculate/spanNs.js +10 -4
  296. package/dist/span/validate/isValidSpan.d.ts +8 -3
  297. package/dist/span/validate/isValidSpan.js +8 -3
  298. package/dist/transport/calculate/bestAvailable.d.ts +47 -0
  299. package/dist/transport/calculate/bestAvailable.js +76 -0
  300. package/dist/transport/calculate/crossingTime.d.ts +58 -0
  301. package/dist/transport/calculate/crossingTime.js +76 -0
  302. package/dist/transport/calculate/cutoffAt.d.ts +90 -0
  303. package/dist/transport/calculate/cutoffAt.js +209 -0
  304. package/dist/transport/calculate/cutoffSchedule.d.ts +70 -0
  305. package/dist/transport/calculate/cutoffSchedule.js +71 -0
  306. package/dist/transport/calculate/dwellTime.d.ts +16 -7
  307. package/dist/transport/calculate/dwellTime.js +12 -8
  308. package/dist/transport/calculate/estimateDrift.d.ts +65 -0
  309. package/dist/transport/calculate/estimateDrift.js +75 -0
  310. package/dist/transport/calculate/index.d.ts +8 -0
  311. package/dist/transport/calculate/index.js +8 -0
  312. package/dist/transport/calculate/nextDeparture.d.ts +78 -0
  313. package/dist/transport/calculate/nextDeparture.js +131 -0
  314. package/dist/transport/calculate/punctualityRate.d.ts +42 -0
  315. package/dist/transport/calculate/punctualityRate.js +59 -0
  316. package/dist/transport/calculate/scheduleDelivery.d.ts +150 -0
  317. package/dist/transport/calculate/scheduleDelivery.js +300 -0
  318. package/dist/transport/calculate/transitTime.d.ts +21 -3
  319. package/dist/transport/calculate/transitTime.js +29 -46
  320. package/dist/transport/compare/classifyPunctuality.d.ts +46 -0
  321. package/dist/transport/compare/classifyPunctuality.js +64 -0
  322. package/dist/transport/compare/index.d.ts +4 -0
  323. package/dist/transport/compare/index.js +4 -0
  324. package/dist/transport/compare/isPastCutoff.d.ts +33 -0
  325. package/dist/transport/compare/isPastCutoff.js +48 -0
  326. package/dist/transport/compare/scheduleDeviation.d.ts +37 -0
  327. package/dist/transport/compare/scheduleDeviation.js +53 -0
  328. package/dist/transport/compare/timeToCutoff.d.ts +31 -0
  329. package/dist/transport/compare/timeToCutoff.js +47 -0
  330. package/dist/transport/convert/etaAtZone.d.ts +7 -0
  331. package/dist/transport/convert/etaAtZone.js +9 -4
  332. package/dist/transport/index.d.ts +1 -0
  333. package/dist/transport/index.js +1 -0
  334. package/dist/types/business-calendar.d.ts +19 -14
  335. package/dist/types/calendar-options.d.ts +15 -3
  336. package/dist/types/date-cycle-field.d.ts +5 -0
  337. package/dist/types/date-duration-unit.d.ts +4 -0
  338. package/dist/types/date-time-cycle-field.d.ts +4 -0
  339. package/dist/types/date-time-duration-units.d.ts +4 -0
  340. package/dist/types/date-time-unit.d.ts +4 -0
  341. package/dist/types/date-unit.d.ts +4 -0
  342. package/dist/types/disambiguation.d.ts +8 -0
  343. package/dist/types/duration-relative-to.d.ts +8 -0
  344. package/dist/types/duration-string-options.d.ts +28 -0
  345. package/dist/types/fiscal-calendar.d.ts +1 -1
  346. package/dist/types/fractional-digit.d.ts +5 -0
  347. package/dist/types/free-time-options.d.ts +21 -11
  348. package/dist/types/index.d.ts +2 -1
  349. package/dist/types/index.js +2 -1
  350. package/dist/types/interval.d.ts +8 -1
  351. package/dist/types/offset.d.ts +9 -0
  352. package/dist/types/operating-schedule.d.ts +71 -0
  353. package/dist/types/overflow.d.ts +6 -0
  354. package/dist/types/relative-rounding-method.d.ts +6 -0
  355. package/dist/types/relative-time-options.d.ts +33 -5
  356. package/dist/types/rounding-options.d.ts +27 -0
  357. package/dist/types/time-cycle-field.d.ts +4 -0
  358. package/dist/types/time-duration-unit.d.ts +4 -0
  359. package/dist/types/time-unit.d.ts +4 -0
  360. package/dist/types/transport-timestamps.d.ts +54 -0
  361. package/dist/types/transport-timestamps.js +0 -0
  362. package/dist/unix/calculate/addUnix.d.ts +19 -5
  363. package/dist/unix/calculate/addUnix.js +1 -5
  364. package/dist/unix/calculate/diffUnix.d.ts +13 -3
  365. package/dist/unix/calculate/diffUnix.js +1 -3
  366. package/dist/unix/calculate/diffUnixAsDuration.d.ts +13 -3
  367. package/dist/unix/calculate/diffUnixAsDuration.js +1 -3
  368. package/dist/unix/calculate/endOfQuarterForUnix.d.ts +13 -3
  369. package/dist/unix/calculate/endOfQuarterForUnix.js +1 -3
  370. package/dist/unix/calculate/endOfUnix.d.ts +20 -4
  371. package/dist/unix/calculate/endOfUnix.js +1 -4
  372. package/dist/unix/calculate/isBetweenUnix.d.ts +26 -4
  373. package/dist/unix/calculate/isBetweenUnix.js +4 -6
  374. package/dist/unix/calculate/roundUnix.d.ts +31 -3
  375. package/dist/unix/calculate/roundUnix.js +3 -6
  376. package/dist/unix/calculate/setUnix.d.ts +35 -9
  377. package/dist/unix/calculate/setUnix.js +4 -13
  378. package/dist/unix/calculate/startOfQuarterForUnix.d.ts +13 -3
  379. package/dist/unix/calculate/startOfQuarterForUnix.js +1 -3
  380. package/dist/unix/calculate/startOfUnix.d.ts +20 -4
  381. package/dist/unix/calculate/startOfUnix.js +1 -4
  382. package/dist/unix/calculate/subtractUnix.d.ts +19 -5
  383. package/dist/unix/calculate/subtractUnix.js +1 -5
  384. package/dist/unix/compare/areUnixEqual.d.ts +7 -1
  385. package/dist/unix/compare/areUnixEqual.js +1 -1
  386. package/dist/unix/compare/areUnixEqualBy.d.ts +24 -7
  387. package/dist/unix/compare/areUnixEqualBy.js +13 -9
  388. package/dist/unix/compare/isAfterUnix.d.ts +7 -1
  389. package/dist/unix/compare/isAfterUnix.js +1 -1
  390. package/dist/unix/compare/isBeforeUnix.d.ts +7 -1
  391. package/dist/unix/compare/isBeforeUnix.js +1 -1
  392. package/dist/unix/convert/convertUnixToPlainDate.d.ts +14 -4
  393. package/dist/unix/convert/convertUnixToPlainDate.js +2 -4
  394. package/dist/unix/convert/convertUnixToPlainDateTime.d.ts +14 -4
  395. package/dist/unix/convert/convertUnixToPlainDateTime.js +2 -4
  396. package/dist/unix/convert/convertUnixToPlainTime.d.ts +14 -4
  397. package/dist/unix/convert/convertUnixToPlainTime.js +2 -4
  398. package/dist/unix/convert/convertUnixToUtc.d.ts +9 -4
  399. package/dist/unix/convert/convertUnixToUtc.js +3 -4
  400. package/dist/unix/convert/convertUnixToZoned.d.ts +10 -5
  401. package/dist/unix/convert/convertUnixToZoned.js +4 -5
  402. package/dist/unix/format/formatCalendarUnix.d.ts +27 -19
  403. package/dist/unix/format/formatCalendarUnix.js +4 -5
  404. package/dist/unix/format/formatRelativeUnix.d.ts +54 -5
  405. package/dist/unix/format/formatRelativeUnix.js +3 -5
  406. package/dist/unix/format/formatUnix.d.ts +24 -6
  407. package/dist/unix/format/formatUnix.js +8 -7
  408. package/dist/unix/get/getUnixNow.d.ts +8 -3
  409. package/dist/unix/get/getUnixNow.js +1 -3
  410. package/dist/unix/interval/intervalCountUnix.d.ts +14 -5
  411. package/dist/unix/interval/intervalCountUnix.js +2 -5
  412. package/dist/unix/interval/intervalDifferenceUnix.d.ts +6 -0
  413. package/dist/unix/interval/intervalDivideEquallyUnix.d.ts +18 -4
  414. package/dist/unix/interval/intervalDivideEquallyUnix.js +5 -4
  415. package/dist/unix/interval/intervalFromDurationUnix.d.ts +33 -5
  416. package/dist/unix/interval/intervalFromDurationUnix.js +6 -5
  417. package/dist/unix/interval/intervalIntersectionUnix.d.ts +6 -0
  418. package/dist/unix/interval/intervalLengthUnix.d.ts +16 -6
  419. package/dist/unix/interval/intervalLengthUnix.js +4 -6
  420. package/dist/unix/interval/intervalOverlappingDaysUnix.d.ts +13 -3
  421. package/dist/unix/interval/intervalOverlappingDaysUnix.js +1 -3
  422. package/dist/unix/interval/intervalSplitAtUnix.d.ts +8 -0
  423. package/dist/unix/interval/intervalSplitAtUnix.js +2 -0
  424. package/dist/unix/interval/intervalUnionUnix.d.ts +6 -0
  425. package/dist/unix/interval/intervalXorAllUnix.d.ts +6 -0
  426. package/dist/unix/interval/intervalXorUnix.d.ts +6 -0
  427. package/dist/unix/interval/mergeIntervalsUnix.d.ts +6 -0
  428. package/dist/unix/interval/splitIntervalByUnitUnix.d.ts +42 -11
  429. package/dist/unix/interval/splitIntervalByUnitUnix.js +21 -16
  430. package/dist/unix/parse/parseDateFromUnix.d.ts +13 -2
  431. package/dist/unix/parse/parseDateFromUnix.js +1 -2
  432. package/dist/unix/parse/parseDayFromUnix.d.ts +14 -2
  433. package/dist/unix/parse/parseDayFromUnix.js +2 -2
  434. package/dist/unix/parse/parseDayOfWeekFromUnix.d.ts +13 -1
  435. package/dist/unix/parse/parseDayOfWeekFromUnix.js +1 -1
  436. package/dist/unix/parse/parseHourFromUnix.d.ts +14 -2
  437. package/dist/unix/parse/parseHourFromUnix.js +2 -2
  438. package/dist/unix/parse/parseMicrosecondFromUnix.d.ts +14 -2
  439. package/dist/unix/parse/parseMicrosecondFromUnix.js +2 -2
  440. package/dist/unix/parse/parseMillisecondFromUnix.d.ts +14 -2
  441. package/dist/unix/parse/parseMillisecondFromUnix.js +2 -2
  442. package/dist/unix/parse/parseMinuteFromUnix.d.ts +14 -2
  443. package/dist/unix/parse/parseMinuteFromUnix.js +2 -2
  444. package/dist/unix/parse/parseMonthFromUnix.d.ts +14 -2
  445. package/dist/unix/parse/parseMonthFromUnix.js +2 -2
  446. package/dist/unix/parse/parseNanosecondFromUnix.d.ts +14 -2
  447. package/dist/unix/parse/parseNanosecondFromUnix.js +2 -2
  448. package/dist/unix/parse/parseSecondFromUnix.d.ts +14 -2
  449. package/dist/unix/parse/parseSecondFromUnix.js +2 -2
  450. package/dist/unix/parse/parseTimeFromUnix.d.ts +13 -2
  451. package/dist/unix/parse/parseTimeFromUnix.js +1 -2
  452. package/dist/unix/parse/parseUnitFromUnix.d.ts +22 -3
  453. package/dist/unix/parse/parseUnitFromUnix.js +2 -3
  454. package/dist/unix/parse/parseWeekFromUnix.d.ts +23 -7
  455. package/dist/unix/parse/parseWeekFromUnix.js +3 -7
  456. package/dist/unix/parse/parseYearFromUnix.d.ts +14 -2
  457. package/dist/unix/parse/parseYearFromUnix.js +2 -2
  458. package/dist/unix/validate/isValidUnixRange.d.ts +20 -4
  459. package/dist/unix/validate/isValidUnixRange.js +1 -4
  460. package/dist/utc/calculate/addUtc.d.ts +7 -4
  461. package/dist/utc/calculate/addUtc.js +1 -4
  462. package/dist/utc/calculate/diffUtc.d.ts +1 -1
  463. package/dist/utc/calculate/diffUtc.js +1 -1
  464. package/dist/utc/calculate/diffUtcAsDuration.d.ts +1 -1
  465. package/dist/utc/calculate/diffUtcAsDuration.js +1 -1
  466. package/dist/utc/calculate/endOfUtc.d.ts +16 -3
  467. package/dist/utc/calculate/endOfUtc.js +2 -3
  468. package/dist/utc/calculate/isBetweenUtc.d.ts +13 -2
  469. package/dist/utc/calculate/isBetweenUtc.js +4 -4
  470. package/dist/utc/calculate/roundUtc.d.ts +26 -9
  471. package/dist/utc/calculate/roundUtc.js +3 -12
  472. package/dist/utc/calculate/setUtc.d.ts +7 -4
  473. package/dist/utc/calculate/setUtc.js +1 -4
  474. package/dist/utc/calculate/startOfUtc.d.ts +15 -2
  475. package/dist/utc/calculate/startOfUtc.js +1 -2
  476. package/dist/utc/calculate/subtractUtc.d.ts +7 -4
  477. package/dist/utc/calculate/subtractUtc.js +1 -4
  478. package/dist/utc/compare/areUtcEqualBy.d.ts +9 -3
  479. package/dist/utc/compare/areUtcEqualBy.js +2 -3
  480. package/dist/utc/convert/convertUtcToPlainDate.d.ts +8 -3
  481. package/dist/utc/convert/convertUtcToPlainDate.js +5 -6
  482. package/dist/utc/convert/convertUtcToPlainDateTime.d.ts +8 -3
  483. package/dist/utc/convert/convertUtcToPlainDateTime.js +5 -6
  484. package/dist/utc/convert/convertUtcToPlainTime.d.ts +8 -3
  485. package/dist/utc/convert/convertUtcToPlainTime.js +5 -6
  486. package/dist/utc/convert/convertUtcToUnix.d.ts +9 -4
  487. package/dist/utc/convert/convertUtcToUnix.js +3 -4
  488. package/dist/utc/convert/convertUtcToZoned.d.ts +1 -1
  489. package/dist/utc/convert/convertUtcToZoned.js +1 -1
  490. package/dist/utc/format/formatCalendarUtc.d.ts +19 -8
  491. package/dist/utc/format/formatCalendarUtc.js +8 -6
  492. package/dist/utc/format/formatHttp.d.ts +1 -1
  493. package/dist/utc/format/formatHttp.js +1 -1
  494. package/dist/utc/format/formatRelativeUtc.d.ts +30 -10
  495. package/dist/utc/format/formatRelativeUtc.js +9 -11
  496. package/dist/utc/format/formatUtc.d.ts +17 -15
  497. package/dist/utc/format/formatUtc.js +8 -8
  498. package/dist/utc/interval/intervalDifferenceUtc.d.ts +6 -0
  499. package/dist/utc/interval/intervalDivideEquallyUtc.d.ts +18 -4
  500. package/dist/utc/interval/intervalDivideEquallyUtc.js +5 -4
  501. package/dist/utc/interval/intervalFromDurationUtc.d.ts +13 -3
  502. package/dist/utc/interval/intervalFromDurationUtc.js +1 -3
  503. package/dist/utc/interval/intervalIntersectionUtc.d.ts +6 -0
  504. package/dist/utc/interval/intervalSplitAtUtc.d.ts +8 -0
  505. package/dist/utc/interval/intervalSplitAtUtc.js +2 -0
  506. package/dist/utc/interval/intervalUnionUtc.d.ts +6 -0
  507. package/dist/utc/interval/intervalXorAllUtc.d.ts +6 -0
  508. package/dist/utc/interval/intervalXorUtc.d.ts +6 -0
  509. package/dist/utc/interval/mergeIntervalsUtc.d.ts +6 -0
  510. package/dist/utc/interval/splitIntervalByUnitUtc.d.ts +19 -6
  511. package/dist/utc/interval/splitIntervalByUnitUtc.js +6 -6
  512. package/dist/utc/parse/parseDateFromUtc.d.ts +7 -3
  513. package/dist/utc/parse/parseDateFromUtc.js +1 -3
  514. package/dist/utc/parse/parseDayFromUtc.d.ts +7 -3
  515. package/dist/utc/parse/parseDayFromUtc.js +1 -3
  516. package/dist/utc/parse/parseDayOfWeekFromUtc.d.ts +7 -3
  517. package/dist/utc/parse/parseDayOfWeekFromUtc.js +4 -6
  518. package/dist/utc/parse/parseHourFromUtc.d.ts +7 -3
  519. package/dist/utc/parse/parseHourFromUtc.js +1 -3
  520. package/dist/utc/parse/parseHttp.d.ts +1 -1
  521. package/dist/utc/parse/parseHttp.js +1 -1
  522. package/dist/utc/parse/parseMicrosecondFromUtc.d.ts +7 -3
  523. package/dist/utc/parse/parseMicrosecondFromUtc.js +1 -3
  524. package/dist/utc/parse/parseMillisecondFromUtc.d.ts +7 -3
  525. package/dist/utc/parse/parseMillisecondFromUtc.js +1 -3
  526. package/dist/utc/parse/parseMinuteFromUtc.d.ts +7 -3
  527. package/dist/utc/parse/parseMinuteFromUtc.js +1 -3
  528. package/dist/utc/parse/parseMonthFromUtc.d.ts +7 -3
  529. package/dist/utc/parse/parseMonthFromUtc.js +1 -3
  530. package/dist/utc/parse/parseNanosecondFromUtc.d.ts +7 -3
  531. package/dist/utc/parse/parseNanosecondFromUtc.js +1 -3
  532. package/dist/utc/parse/parseSecondFromUtc.d.ts +7 -3
  533. package/dist/utc/parse/parseSecondFromUtc.js +1 -3
  534. package/dist/utc/parse/parseTimeFromUtc.d.ts +8 -3
  535. package/dist/utc/parse/parseTimeFromUtc.js +5 -6
  536. package/dist/utc/parse/parseUnitFromUtc.d.ts +17 -5
  537. package/dist/utc/parse/parseUnitFromUtc.js +6 -8
  538. package/dist/utc/parse/parseWeekFromUtc.d.ts +18 -10
  539. package/dist/utc/parse/parseWeekFromUtc.js +7 -13
  540. package/dist/utc/parse/parseYearFromUtc.d.ts +7 -3
  541. package/dist/utc/parse/parseYearFromUtc.js +1 -3
  542. package/dist/utc/validate/isValidUtcRange.d.ts +16 -5
  543. package/dist/utc/validate/isValidUtcRange.js +2 -5
  544. package/dist/zoned/calculate/addZoned.d.ts +20 -10
  545. package/dist/zoned/calculate/addZoned.js +6 -13
  546. package/dist/zoned/calculate/cycleZoned.d.ts +33 -8
  547. package/dist/zoned/calculate/cycleZoned.js +1 -8
  548. package/dist/zoned/calculate/diffZoned.d.ts +1 -1
  549. package/dist/zoned/calculate/diffZoned.js +1 -1
  550. package/dist/zoned/calculate/diffZonedAsDuration.d.ts +1 -1
  551. package/dist/zoned/calculate/diffZonedAsDuration.js +1 -1
  552. package/dist/zoned/calculate/endOfQuarterForZoned.d.ts +9 -2
  553. package/dist/zoned/calculate/endOfQuarterForZoned.js +4 -5
  554. package/dist/zoned/calculate/endOfZoned.d.ts +16 -3
  555. package/dist/zoned/calculate/endOfZoned.js +2 -3
  556. package/dist/zoned/calculate/getLocaleZonedEndOfWeek.d.ts +10 -3
  557. package/dist/zoned/calculate/getLocaleZonedEndOfWeek.js +5 -6
  558. package/dist/zoned/calculate/getLocaleZonedStartOfWeek.d.ts +7 -1
  559. package/dist/zoned/calculate/getLocaleZonedStartOfWeek.js +3 -4
  560. package/dist/zoned/calculate/roundZoned.d.ts +21 -4
  561. package/dist/zoned/calculate/roundZoned.js +3 -7
  562. package/dist/zoned/calculate/setZoned.d.ts +25 -8
  563. package/dist/zoned/calculate/setZoned.js +4 -12
  564. package/dist/zoned/calculate/startOfQuarterForZoned.d.ts +7 -2
  565. package/dist/zoned/calculate/startOfQuarterForZoned.js +3 -5
  566. package/dist/zoned/calculate/startOfZoned.d.ts +15 -3
  567. package/dist/zoned/calculate/startOfZoned.js +1 -3
  568. package/dist/zoned/calculate/subtractZoned.d.ts +20 -10
  569. package/dist/zoned/calculate/subtractZoned.js +6 -13
  570. package/dist/zoned/compare/areZonedEqualBy.d.ts +14 -5
  571. package/dist/zoned/compare/areZonedEqualBy.js +7 -5
  572. package/dist/zoned/compare/isBetweenZoned.d.ts +13 -1
  573. package/dist/zoned/compare/isBetweenZoned.js +4 -3
  574. package/dist/zoned/compare/isInDaylightSaving.d.ts +38 -11
  575. package/dist/zoned/compare/isInDaylightSaving.js +40 -44
  576. package/dist/zoned/convert/convertPlainDateTimeToZoned.d.ts +18 -5
  577. package/dist/zoned/convert/convertPlainDateTimeToZoned.js +6 -11
  578. package/dist/zoned/convert/convertZonedToUnix.d.ts +9 -4
  579. package/dist/zoned/convert/convertZonedToUnix.js +2 -4
  580. package/dist/zoned/convert/convertZonedToZoned.d.ts +1 -1
  581. package/dist/zoned/convert/convertZonedToZoned.js +1 -1
  582. package/dist/zoned/format/formatCalendarZoned.d.ts +18 -12
  583. package/dist/zoned/format/formatCalendarZoned.js +13 -9
  584. package/dist/zoned/format/formatRelativeZoned.d.ts +41 -12
  585. package/dist/zoned/format/formatRelativeZoned.js +7 -4
  586. package/dist/zoned/format/formatRfc2822.d.ts +2 -2
  587. package/dist/zoned/format/formatRfc2822.js +2 -2
  588. package/dist/zoned/format/formatRfc3339.d.ts +2 -3
  589. package/dist/zoned/format/formatRfc3339.js +2 -3
  590. package/dist/zoned/format/formatTimeZoneName.d.ts +12 -3
  591. package/dist/zoned/format/formatTimeZoneName.js +5 -4
  592. package/dist/zoned/format/formatZonedDateTime.js +2 -1
  593. package/dist/zoned/format/formatZonedRange.js +2 -1
  594. package/dist/zoned/format/formatZonedToParts.d.ts +15 -4
  595. package/dist/zoned/format/formatZonedToParts.js +8 -5
  596. package/dist/zoned/get/getDstTransitions.d.ts +9 -10
  597. package/dist/zoned/get/getDstTransitions.js +12 -3
  598. package/dist/zoned/get/getTimeZoneOffset.d.ts +4 -1
  599. package/dist/zoned/get/getTimeZoneOffset.js +6 -3
  600. package/dist/zoned/get/getZonedNow.d.ts +13 -1
  601. package/dist/zoned/get/getZonedNow.js +12 -3
  602. package/dist/zoned/interval/intervalDifferenceZoned.d.ts +9 -0
  603. package/dist/zoned/interval/intervalDivideEquallyZoned.d.ts +22 -4
  604. package/dist/zoned/interval/intervalDivideEquallyZoned.js +6 -4
  605. package/dist/zoned/interval/intervalFromDurationZoned.d.ts +29 -10
  606. package/dist/zoned/interval/intervalFromDurationZoned.js +6 -13
  607. package/dist/zoned/interval/intervalIntersectionZoned.d.ts +9 -0
  608. package/dist/zoned/interval/intervalSplitAtZoned.d.ts +11 -0
  609. package/dist/zoned/interval/intervalSplitAtZoned.js +2 -0
  610. package/dist/zoned/interval/intervalUnionZoned.d.ts +9 -0
  611. package/dist/zoned/interval/intervalXorAllZoned.d.ts +9 -0
  612. package/dist/zoned/interval/intervalXorZoned.d.ts +9 -0
  613. package/dist/zoned/interval/mergeIntervalsZoned.d.ts +9 -0
  614. package/dist/zoned/interval/splitIntervalByUnitZoned.d.ts +27 -6
  615. package/dist/zoned/interval/splitIntervalByUnitZoned.js +11 -6
  616. package/dist/zoned/map/mapZonedDatesInRange.d.ts +9 -4
  617. package/dist/zoned/map/mapZonedDatesInRange.js +2 -4
  618. package/dist/zoned/parse/parseRfc2822.d.ts +1 -1
  619. package/dist/zoned/parse/parseRfc2822.js +1 -1
  620. package/dist/zoned/parse/parseUnitFromZoned.d.ts +9 -3
  621. package/dist/zoned/parse/parseUnitFromZoned.js +1 -3
  622. package/dist/zoned/parse/parseWeekFromZoned.d.ts +10 -3
  623. package/dist/zoned/parse/parseWeekFromZoned.js +2 -3
  624. package/dist/zoned/validate/hasDaylightSaving.d.ts +42 -11
  625. package/dist/zoned/validate/hasDaylightSaving.js +47 -31
  626. package/dist/zoned/validate/isValidZonedDateTime.d.ts +13 -0
  627. package/dist/zoned/validate/isValidZonedDateTime.js +14 -1
  628. package/dist/zoned/validate/isValidZonedRange.d.ts +15 -4
  629. package/dist/zoned/validate/isValidZonedRange.js +1 -4
  630. package/package.json +18 -5
  631. package/skills/gmt-arithmetic/SKILL.md +1 -1
  632. package/skills/gmt-basics/SKILL.md +10 -1
  633. package/skills/gmt-integration/SKILL.md +10 -5
  634. package/skills/gmt-timezone/SKILL.md +150 -21
  635. package/dist/internal/resolveReadingTimeZone.d.ts +0 -11
  636. package/dist/internal/resolveReadingTimeZone.js +0 -18
  637. package/dist/types/duration-unit.d.ts +0 -5
  638. /package/dist/types/{duration-unit.js → operating-schedule.js} +0 -0
@@ -0,0 +1,209 @@
1
+ import { Temporal } from "@js-temporal/polyfill";
2
+ import { rollDate } from "../../calendar/business/rollDate.js";
3
+ import { isValidBusinessCalendar } from "../../calendar/validate/isValidBusinessCalendar.js";
4
+ import { isValidRollConvention } from "../../calendar/validate/isValidRollConvention.js";
5
+ import { isValidDuration } from "../../duration/validate/isValidDuration.js";
6
+ import { classifyLocal } from "../../instant/convert/classifyLocal.js";
7
+ import { resolveLocal } from "../../instant/convert/resolveLocal.js";
8
+ import { instantFrom } from "../../internal/index.js";
9
+ import { isObject } from "../../internal/isObject.js";
10
+ import { isValidTime } from "../../plain/validate/isValidTime.js";
11
+ import { isValidInstant } from "../../precision/validate/isValidInstant.js";
12
+ import { isValidTimeZone } from "../../zoned/validate/isValidTimeZone.js";
13
+ function resolveOptions(options) {
14
+ if (!isObject(options)) {
15
+ return null;
16
+ }
17
+ const { timeZone, atLocalTime, calendar, roll } = options;
18
+ if (typeof timeZone !== "string" || !isValidTimeZone(timeZone)) {
19
+ return null;
20
+ }
21
+ if (atLocalTime !== undefined && !isValidTime(atLocalTime)) {
22
+ return null;
23
+ }
24
+ if (calendar !== undefined && !isValidBusinessCalendar(calendar)) {
25
+ return null;
26
+ }
27
+ if (roll !== undefined && !isValidRollConvention(roll)) {
28
+ return null;
29
+ }
30
+ // Rolling needs both a calendar and a direction, and no standard supplies either one by
31
+ // default: a calendar without a roll, or a roll without a calendar, is a missing term.
32
+ if ((calendar === undefined) !== (roll === undefined)) {
33
+ return null;
34
+ }
35
+ return {
36
+ timeZone,
37
+ atLocalTime: atLocalTime === undefined ? null : Temporal.PlainTime.from(atLocalTime),
38
+ rolling: calendar === undefined || roll === undefined ? null : { calendar, roll },
39
+ };
40
+ }
41
+ /**
42
+ * The instant a local wall time names: the first occurrence of a repeated hour, as RFC 5545
43
+ * §3.3.5 reads a local time that "occurs more than once", and `null` for a skipped one, which
44
+ * is never shifted.
45
+ */
46
+ function resolveWallTime(wall, timeZone) {
47
+ const local = wall.toString();
48
+ const kind = classifyLocal(local, timeZone);
49
+ if (kind === null || kind === "nonexistent") {
50
+ return null;
51
+ }
52
+ const instant = resolveLocal(local, timeZone, { disambiguation: "earlier" });
53
+ return instant === ""
54
+ ? null
55
+ : Temporal.Instant.from(instant).toZonedDateTimeISO(timeZone);
56
+ }
57
+ /** The calendar part of a duration — years, months, weeks and days. */
58
+ function datePart(offset) {
59
+ return Temporal.Duration.from({
60
+ years: offset.years,
61
+ months: offset.months,
62
+ weeks: offset.weeks,
63
+ days: offset.days,
64
+ });
65
+ }
66
+ /** The exact part of a duration — hours and smaller. */
67
+ function timePart(offset) {
68
+ return Temporal.Duration.from({
69
+ hours: offset.hours,
70
+ minutes: offset.minutes,
71
+ seconds: offset.seconds,
72
+ milliseconds: offset.milliseconds,
73
+ microseconds: offset.microseconds,
74
+ nanoseconds: offset.nanoseconds,
75
+ });
76
+ }
77
+ /**
78
+ * The offset taken off the anchor with no pinning: the calendar part moves the local wall
79
+ * clock, then the exact part comes off in exact time — Temporal's `ZonedDateTime#subtract`,
80
+ * except that a wall clock landing in a skipped hour is `null` rather than moved forward.
81
+ */
82
+ function subtractOffset(anchor, offset) {
83
+ const calendarPart = datePart(offset);
84
+ if (calendarPart.blank) {
85
+ return anchor.subtract(timePart(offset));
86
+ }
87
+ const wall = resolveWallTime(anchor.toPlainDateTime().subtract(calendarPart), anchor.timeZoneId);
88
+ return wall === null ? null : wall.subtract(timePart(offset));
89
+ }
90
+ /**
91
+ * The local date the cut-off falls on after rolling, or `null` when the roll fails. With no
92
+ * calendar the date is left as it is.
93
+ */
94
+ function rolledDate(date, options) {
95
+ if (options.rolling === null) {
96
+ return date;
97
+ }
98
+ const { calendar, roll } = options.rolling;
99
+ const rolled = rollDate(date.toString(), roll, calendar);
100
+ return rolled === "" ? null : Temporal.PlainDate.from(rolled);
101
+ }
102
+ /**
103
+ * Find a deadline stated as an offset before an anchor event, in the local time of the place
104
+ * that enforces it.
105
+ *
106
+ * Logistics deadlines are not fixed timestamps: they count back from an event — a vessel's
107
+ * departure, a flight's, a container's loading — and they move when that event moves. An ocean
108
+ * booking carries a stack of them (documentation, VGM, gate-in, customs); `cutoffSchedule`
109
+ * computes the whole stack at once.
110
+ *
111
+ * - **`atLocalTime` is what makes this more than subtracting a duration.** A cut-off "two days
112
+ * before, 17:00" is 17:00 local on the date two days earlier — not 48 hours before, which
113
+ * keeps the departure's time of day, and moves by an hour when a DST transition falls in
114
+ * between. With `atLocalTime` only the day of the offset result matters: the offset's exact
115
+ * part (hours and smaller) comes off the anchor's instant, its calendar part (years, months,
116
+ * weeks, days) off that local date, and the cut-off is `atLocalTime` on the day it lands on.
117
+ * Because the exact part is taken off before the day is found, it can change the day: from
118
+ * midnight, `P2DT0.000000001S` lands a day earlier than `P2D`.
119
+ * - **Without `atLocalTime` the offset is taken off as Temporal's `ZonedDateTime#subtract`
120
+ * takes it:** the calendar part moves the local wall clock — `P2D` from 18:00 is 18:00, 47,
121
+ * 48 or 49 hours earlier — and the exact part is exact elapsed time — `PT96H` is 96 hours,
122
+ * whatever the clock does. This is the advance-filing shape.
123
+ * - **The anchor is the caller's event.** Loading, departure and arrival are different
124
+ * instants, and the same offset from the wrong one is late by days. `cutoffAt` never guesses
125
+ * which event a rule means. The anchor is exact: an instant (`Z`/offset) or a zoned string.
126
+ * Its bracket never supplies the zone — `timeZone` alone is the local frame — and is not
127
+ * checked, with one exception: an offset written to the minute that is the bracketed zone's
128
+ * sub-minute offset rounded (`-00:45[Africa/Monrovia]`, for −00:44:30) names the instant the
129
+ * zone gives, as `Temporal.ZonedDateTime.from` reads it. The anchor is not cached: a
130
+ * rescheduled departure is a new call.
131
+ * - **Non-business days roll as the caller says.** With `calendar`, a cut-off on a weekend or
132
+ * holiday moves by `roll`, as `rollDate` moves it. Every industry answers "what if it lands
133
+ * on a non-working day" differently, so the convention is always explicit — there is no
134
+ * default: `calendar` without `roll`, or `roll` without `calendar`, returns `""`. The rolled
135
+ * day keeps the cut-off's local time of day. `calendar.timeZone` is not read; `timeZone` is
136
+ * the local frame. `"endOfMonth"` is `rollDate`'s schedule tool, not a cut-off convention.
137
+ * - **The order is not checked.** `cutoffAt` does not check that the cut-off comes before the
138
+ * anchor: a negative offset, `P0D` with a late `atLocalTime`, `"following"` or `"endOfMonth"`
139
+ * can each put it after.
140
+ * - **Local-time resolution.** Every local wall time the cut-off lands on — `atLocalTime`, the
141
+ * calendar part of an unpinned offset, a rolled day — is resolved as `resolveLocal` describes
142
+ * it: an **ambiguous** wall time (a fall-back hour the clock ran through twice) takes the
143
+ * **earlier** instant — RFC 5545 §3.3.5's "first occurrence of the referenced time" — and a
144
+ * **nonexistent** one (a skipped hour, a deleted day) returns `""` rather than being
145
+ * shifted. An exact result that is not re-resolved stays as it is.
146
+ * - Returns the cut-off as a zoned string in `timeZone`, or `""` on invalid input.
147
+ *
148
+ * @param anchor ISO 8601 instant or zoned datetime string of the event the deadline counts back from
149
+ * @param offset ISO 8601 duration before the anchor
150
+ * @param options The zone the cut-off is read in, the time of day it is pinned to, and how it rolls off a non-business day
151
+ * @returns ISO 8601 zoned datetime string of the cut-off, or "" on invalid input
152
+ *
153
+ * @example cutoffAt("2024-06-14T16:00:00Z", "P2D", { timeZone: "Europe/Amsterdam", atLocalTime: "17:00" }) // "2024-06-12T17:00:00+02:00[Europe/Amsterdam]"
154
+ * @example cutoffAt("2024-06-14T16:00:00Z", "PT48H", { timeZone: "Europe/Amsterdam" }) // "2024-06-12T18:00:00+02:00[Europe/Amsterdam]" (48 hours keeps the departure's 18:00)
155
+ * @example cutoffAt("2024-06-14T16:00:00Z", "P1D", { timeZone: "Europe/Amsterdam", atLocalTime: "10:00" }) // "2024-06-13T10:00:00+02:00[Europe/Amsterdam]"
156
+ * @example cutoffAt("2024-11-05T17:00:00Z", "PT96H", { timeZone: "America/New_York" }) // "2024-11-01T13:00:00-04:00[America/New_York]" (96 elapsed hours across the fall-back)
157
+ * @example cutoffAt("2024-03-11T22:00:00Z", "P2D", { timeZone: "America/New_York", atLocalTime: "17:00" }) // "2024-03-09T17:00:00-05:00[America/New_York]" (17:00 local, across the spring-forward)
158
+ * @example cutoffAt("2024-06-18T16:00:00Z", "P2D", { timeZone: "Europe/Amsterdam", atLocalTime: "17:00", calendar: { weekend: [6, 7], holidays: [], timeZone: "Europe/Amsterdam" }, roll: "preceding" }) // "2024-06-14T17:00:00+02:00[Europe/Amsterdam]" (Sunday rolls back to Friday)
159
+ * @example cutoffAt("2024-06-18T16:00:00Z", "P2D", { timeZone: "Europe/Amsterdam", atLocalTime: "17:00", calendar: { weekend: [6, 7], holidays: [], timeZone: "Europe/Amsterdam" } }) // "" (a calendar needs a roll convention)
160
+ * @example cutoffAt("2024-11-04T23:00:00Z", "P1D", { timeZone: "America/New_York", atLocalTime: "01:30" }) // "2024-11-03T01:30:00-04:00[America/New_York]" (a repeated hour takes the earlier pass)
161
+ * @example cutoffAt("2024-03-11T22:00:00Z", "P1D", { timeZone: "America/New_York", atLocalTime: "02:30" }) // "" (02:30 on 10 March never happened)
162
+ * @example cutoffAt("2024-06-14T18:00:00", "P2D", { timeZone: "Europe/Amsterdam" }) // "" (a zoneless anchor is not a moment)
163
+ * @example cutoffAt("2024-06-14T16:00:00Z", "P2D", { timeZone: "Europe/Amsterdam", roll: "preceding" }) // "" (a roll needs a calendar)
164
+ */
165
+ export function cutoffAt(anchor, offset, options) {
166
+ try {
167
+ const resolved = resolveOptions(options);
168
+ if (resolved === null ||
169
+ !isValidInstant(anchor) ||
170
+ !isValidDuration(offset)) {
171
+ return "";
172
+ }
173
+ try {
174
+ const start = instantFrom(anchor).toZonedDateTimeISO(resolved.timeZone);
175
+ const duration = Temporal.Duration.from(offset);
176
+ if (resolved.atLocalTime !== null) {
177
+ const day = rolledDate(start
178
+ .subtract(timePart(duration))
179
+ .toPlainDate()
180
+ .subtract(datePart(duration)), resolved);
181
+ const pinned = day === null
182
+ ? null
183
+ : resolveWallTime(day.toPlainDateTime(resolved.atLocalTime), resolved.timeZone);
184
+ return pinned === null ? "" : pinned.toString();
185
+ }
186
+ const cutoff = subtractOffset(start, duration);
187
+ if (cutoff === null) {
188
+ return "";
189
+ }
190
+ const day = rolledDate(cutoff.toPlainDate(), resolved);
191
+ if (day === null) {
192
+ return "";
193
+ }
194
+ if (day.equals(cutoff.toPlainDate())) {
195
+ return cutoff.toString();
196
+ }
197
+ const rolled = resolveWallTime(day.toPlainDateTime(cutoff.toPlainTime()), resolved.timeZone);
198
+ return rolled === null ? "" : rolled.toString();
199
+ }
200
+ catch {
201
+ return "";
202
+ }
203
+ }
204
+ catch {
205
+ // Never throws (Core Rule 3): a hostile
206
+ // argument is invalid input, not an exception.
207
+ return "";
208
+ }
209
+ }
@@ -0,0 +1,70 @@
1
+ import { type CutoffOptions } from "./cutoffAt.js";
2
+ /** One named deadline in a cut-off stack: how long before the anchor, and at what local time. */
3
+ export interface Cutoff {
4
+ /** The caller's label, echoed back (`"document"`, `"VGM"`); GMT does not interpret it. */
5
+ name: string;
6
+ /** The ISO 8601 duration before the anchor, as `cutoffAt` takes it. */
7
+ offset: string;
8
+ /**
9
+ * The local time of day the cut-off is pinned to, as `cutoffAt` takes it.
10
+ *
11
+ * @defaultValue None. The cut-off is the offset taken off the anchor, with no time of day
12
+ * pinned.
13
+ */
14
+ atLocalTime?: string;
15
+ }
16
+ /** One computed deadline in a cut-off schedule. */
17
+ export interface CutoffTime {
18
+ /** The entry's `name`, echoed back. */
19
+ name: string;
20
+ /** The cut-off as a zoned string in the options' `timeZone`. */
21
+ at: string;
22
+ }
23
+ /** Options for `cutoffSchedule`: `cutoffAt`'s, with `atLocalTime` read from each entry instead. */
24
+ export interface CutoffScheduleOptions {
25
+ /** The time zone every cut-off is read in: an IANA name or a UTC offset. */
26
+ timeZone: string;
27
+ /**
28
+ * The working week and holidays every cut-off's local date is rolled against. Requires `roll`.
29
+ *
30
+ * @defaultValue None. No cut-off's date is rolled; a `roll` without it returns `[]`.
31
+ */
32
+ calendar?: CutoffOptions["calendar"];
33
+ /**
34
+ * How a cut-off on a non-business day moves, as `rollDate` moves it. Requires `calendar`.
35
+ *
36
+ * @defaultValue None. No cut-off's date is rolled; a `calendar` without it returns `[]`.
37
+ */
38
+ roll?: CutoffOptions["roll"];
39
+ }
40
+ /**
41
+ * Compute a whole stack of cut-offs against one anchor event, earliest first.
42
+ *
43
+ * An ocean booking carries several deadlines counted back from the same departure —
44
+ * documentation, VGM, gate-in, customs — and when the vessel is rescheduled all of them move.
45
+ * `cutoffSchedule` computes each entry with `cutoffAt` against the one anchor, so a new
46
+ * departure is one call and every deadline follows it.
47
+ *
48
+ * - Each entry is `cutoffAt(anchor, entry.offset, { ...options, atLocalTime: entry.atLocalTime })`:
49
+ * the same local-time resolution, the same rolling, the same sentinel. `atLocalTime` belongs
50
+ * to the entry; one in `options` is not read.
51
+ * - Sorted earliest first by instant, not by the text of the local time: on a fall-back day
52
+ * 01:30 on the first pass is before 01:15 on the second. Entries on the same instant keep the
53
+ * order they were given in.
54
+ * - `name` is an opaque string echoed back; duplicates are kept.
55
+ * - Every entry must succeed: one invalid entry, or one cut-off in a skipped local hour,
56
+ * returns `[]` rather than a stack with a deadline silently missing. An empty `cutoffs` array
57
+ * returns `[]`.
58
+ *
59
+ * @param anchor ISO 8601 instant or zoned datetime string of the event the deadlines count back from
60
+ * @param cutoffs the named deadlines, each with an offset and an optional local time of day
61
+ * @param options The zone every cut-off is read in, and how one rolls off a non-business day, as cutoffAt takes them
62
+ * @returns the named cut-offs, earliest first, or [] on invalid input
63
+ *
64
+ * @example cutoffSchedule("2024-06-14T16:00:00Z", [{ name: "gate-in", offset: "P1D" }, { name: "document", offset: "P2D", atLocalTime: "17:00" }, { name: "VGM", offset: "P1D", atLocalTime: "10:00" }], { timeZone: "Europe/Amsterdam" }) // [{ name: "document", at: "2024-06-12T17:00:00+02:00[Europe/Amsterdam]" }, { name: "VGM", at: "2024-06-13T10:00:00+02:00[Europe/Amsterdam]" }, { name: "gate-in", at: "2024-06-13T18:00:00+02:00[Europe/Amsterdam]" }]
65
+ * @example cutoffSchedule("2024-06-18T16:00:00Z", [{ name: "document", offset: "P2D", atLocalTime: "17:00" }, { name: "VGM", offset: "P1D", atLocalTime: "10:00" }], { timeZone: "Europe/Amsterdam", calendar: { weekend: [6, 7], holidays: [], timeZone: "Europe/Amsterdam" }, roll: "preceding" }) // [{ name: "document", at: "2024-06-14T17:00:00+02:00[Europe/Amsterdam]" }, { name: "VGM", at: "2024-06-17T10:00:00+02:00[Europe/Amsterdam]" }] (Sunday's document cut-off rolls back to Friday)
66
+ * @example cutoffSchedule("2024-06-14T16:00:00Z", [], { timeZone: "Europe/Amsterdam" }) // []
67
+ * @example cutoffSchedule("2024-06-14T16:00:00Z", [{ name: "document", offset: "2 days" }], { timeZone: "Europe/Amsterdam" }) // []
68
+ * @example cutoffSchedule("2024-03-11T22:00:00Z", [{ name: "gate-in", offset: "P1D" }, { name: "VGM", offset: "P1D", atLocalTime: "02:30" }], { timeZone: "America/New_York" }) // [] (02:30 on 10 March never happened)
69
+ */
70
+ export declare function cutoffSchedule(anchor: string, cutoffs: Cutoff[], options: CutoffScheduleOptions): CutoffTime[];
@@ -0,0 +1,71 @@
1
+ import { Temporal } from "@js-temporal/polyfill";
2
+ import { instantFrom } from "../../internal/index.js";
3
+ import { isObject } from "../../internal/isObject.js";
4
+ import { cutoffAt } from "./cutoffAt.js";
5
+ /**
6
+ * Compute a whole stack of cut-offs against one anchor event, earliest first.
7
+ *
8
+ * An ocean booking carries several deadlines counted back from the same departure —
9
+ * documentation, VGM, gate-in, customs — and when the vessel is rescheduled all of them move.
10
+ * `cutoffSchedule` computes each entry with `cutoffAt` against the one anchor, so a new
11
+ * departure is one call and every deadline follows it.
12
+ *
13
+ * - Each entry is `cutoffAt(anchor, entry.offset, { ...options, atLocalTime: entry.atLocalTime })`:
14
+ * the same local-time resolution, the same rolling, the same sentinel. `atLocalTime` belongs
15
+ * to the entry; one in `options` is not read.
16
+ * - Sorted earliest first by instant, not by the text of the local time: on a fall-back day
17
+ * 01:30 on the first pass is before 01:15 on the second. Entries on the same instant keep the
18
+ * order they were given in.
19
+ * - `name` is an opaque string echoed back; duplicates are kept.
20
+ * - Every entry must succeed: one invalid entry, or one cut-off in a skipped local hour,
21
+ * returns `[]` rather than a stack with a deadline silently missing. An empty `cutoffs` array
22
+ * returns `[]`.
23
+ *
24
+ * @param anchor ISO 8601 instant or zoned datetime string of the event the deadlines count back from
25
+ * @param cutoffs the named deadlines, each with an offset and an optional local time of day
26
+ * @param options The zone every cut-off is read in, and how one rolls off a non-business day, as cutoffAt takes them
27
+ * @returns the named cut-offs, earliest first, or [] on invalid input
28
+ *
29
+ * @example cutoffSchedule("2024-06-14T16:00:00Z", [{ name: "gate-in", offset: "P1D" }, { name: "document", offset: "P2D", atLocalTime: "17:00" }, { name: "VGM", offset: "P1D", atLocalTime: "10:00" }], { timeZone: "Europe/Amsterdam" }) // [{ name: "document", at: "2024-06-12T17:00:00+02:00[Europe/Amsterdam]" }, { name: "VGM", at: "2024-06-13T10:00:00+02:00[Europe/Amsterdam]" }, { name: "gate-in", at: "2024-06-13T18:00:00+02:00[Europe/Amsterdam]" }]
30
+ * @example cutoffSchedule("2024-06-18T16:00:00Z", [{ name: "document", offset: "P2D", atLocalTime: "17:00" }, { name: "VGM", offset: "P1D", atLocalTime: "10:00" }], { timeZone: "Europe/Amsterdam", calendar: { weekend: [6, 7], holidays: [], timeZone: "Europe/Amsterdam" }, roll: "preceding" }) // [{ name: "document", at: "2024-06-14T17:00:00+02:00[Europe/Amsterdam]" }, { name: "VGM", at: "2024-06-17T10:00:00+02:00[Europe/Amsterdam]" }] (Sunday's document cut-off rolls back to Friday)
31
+ * @example cutoffSchedule("2024-06-14T16:00:00Z", [], { timeZone: "Europe/Amsterdam" }) // []
32
+ * @example cutoffSchedule("2024-06-14T16:00:00Z", [{ name: "document", offset: "2 days" }], { timeZone: "Europe/Amsterdam" }) // []
33
+ * @example cutoffSchedule("2024-03-11T22:00:00Z", [{ name: "gate-in", offset: "P1D" }, { name: "VGM", offset: "P1D", atLocalTime: "02:30" }], { timeZone: "America/New_York" }) // [] (02:30 on 10 March never happened)
34
+ */
35
+ export function cutoffSchedule(anchor, cutoffs, options) {
36
+ try {
37
+ if (!Array.isArray(cutoffs) || !isObject(options)) {
38
+ return [];
39
+ }
40
+ const { timeZone, calendar, roll } = options;
41
+ const schedule = [];
42
+ for (const cutoff of cutoffs) {
43
+ if (!isObject(cutoff)) {
44
+ return [];
45
+ }
46
+ const { name, offset, atLocalTime } = cutoff;
47
+ if (typeof name !== "string") {
48
+ return [];
49
+ }
50
+ const at = cutoffAt(anchor, offset, {
51
+ timeZone,
52
+ atLocalTime,
53
+ calendar,
54
+ roll,
55
+ });
56
+ if (at === "") {
57
+ return [];
58
+ }
59
+ schedule.push({ name, at, instant: instantFrom(at) });
60
+ }
61
+ // Array.prototype.sort is stable, so entries on the same instant keep their input order.
62
+ return schedule
63
+ .sort((a, b) => Temporal.Instant.compare(a.instant, b.instant))
64
+ .map(({ name, at }) => ({ name, at }));
65
+ }
66
+ catch {
67
+ // Never throws (Core Rule 3): a hostile
68
+ // argument is invalid input, not an exception.
69
+ return [];
70
+ }
71
+ }
@@ -1,12 +1,17 @@
1
1
  /** What `dwellTime` returns: exact elapsed time plus the local view every charging regime counts in. */
2
2
  export interface Dwell {
3
- /** Exact elapsed time from entry to exit, as an ISO 8601 duration with hours as the largest unit. */
3
+ /**
4
+ * The exact elapsed time from entry to exit, as an ISO 8601 duration with hours as the largest
5
+ * unit.
6
+ */
4
7
  duration: string;
5
8
  /** The entry, rendered in the dwell zone. */
6
9
  enter: string;
7
10
  /** The exit, rendered in the dwell zone. */
8
11
  exit: string;
9
- /** Distinct local calendar dates the dwell touched, counted half-open at the exit. */
12
+ /**
13
+ * The number of distinct local calendar dates the dwell touched, counted half-open at the exit.
14
+ */
10
15
  calendarDays: number;
11
16
  }
12
17
  /**
@@ -34,12 +39,16 @@ export interface Dwell {
34
39
  * touched (`Pacific/Apia` skipped 2011-12-30); and a date the clock falls back into is still
35
40
  * one date (`America/Goose_Bay` fell back from 00:01 on 7 November 2010 into the 6th).
36
41
  * - **The zone decides the count, so it has to be stated.** `targetZone` is used when given.
37
- * Without it, the entry's bracketed IANA zone is used. As in `Temporal.Instant.from`, a
38
- * bracketed zone is otherwise not read, so it is not validated either: the entry's is read
39
- * (and must exist and agree with its offset) only when it supplies the dwell zone, because
40
- * `targetZone` is omitted, and the exit's is never read. If the entry and exit are bare
41
- * instants — `Z` or an offset — and no `targetZone` is given, the result is `null`: an
42
+ * Without it, the entry's bracketed IANA zone is used. A bracketed zone is otherwise not
43
+ * validated: the entry's must exist and agree with its offset only when it supplies the dwell
44
+ * zone, because `targetZone` is omitted, and the exit's never supplies it. If the entry and
45
+ * exit are bare instants — `Z` or an offset — and no `targetZone` is given, the result is `null`: an
42
46
  * offset is not a zone (CORE-4), and a day count in an unstated locality would be a guess.
47
+ * - **The offset fixes each instant; a bracketed zone only resolves a rounded one.** An offset
48
+ * written to the minute that is the bracketed zone's sub-minute offset rounded
49
+ * (`-00:45[Africa/Monrovia]`, for −00:44:30) names the instant the zone gives, as
50
+ * `Temporal.ZonedDateTime.from` reads it, on the entry and the exit alike. A zone that does
51
+ * not exist, or that disagrees with the offset, changes nothing.
43
52
  * - `enter` and `exit` are the two instants rendered in the dwell zone, so a charging record
44
53
  * shows the local times the terminal's own clock showed.
45
54
  * - `targetZone` is whatever `isValidTimeZone` accepts, which is what Temporal accepts: an IANA
@@ -1,5 +1,5 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
- import { countZonedLocalDates, zonedDateTimeFrom } from "../../internal/index.js";
2
+ import { countZonedLocalDates, instantFrom, zonedDateTimeFrom, } from "../../internal/index.js";
3
3
  import { isValidInstant } from "../../precision/validate/isValidInstant.js";
4
4
  import { isValidTimeZone } from "../../zoned/validate/isValidTimeZone.js";
5
5
  import { isValidZonedDateTime } from "../../zoned/validate/isValidZonedDateTime.js";
@@ -48,12 +48,16 @@ function dwellZone(entry, targetZone) {
48
48
  * touched (`Pacific/Apia` skipped 2011-12-30); and a date the clock falls back into is still
49
49
  * one date (`America/Goose_Bay` fell back from 00:01 on 7 November 2010 into the 6th).
50
50
  * - **The zone decides the count, so it has to be stated.** `targetZone` is used when given.
51
- * Without it, the entry's bracketed IANA zone is used. As in `Temporal.Instant.from`, a
52
- * bracketed zone is otherwise not read, so it is not validated either: the entry's is read
53
- * (and must exist and agree with its offset) only when it supplies the dwell zone, because
54
- * `targetZone` is omitted, and the exit's is never read. If the entry and exit are bare
55
- * instants — `Z` or an offset — and no `targetZone` is given, the result is `null`: an
51
+ * Without it, the entry's bracketed IANA zone is used. A bracketed zone is otherwise not
52
+ * validated: the entry's must exist and agree with its offset only when it supplies the dwell
53
+ * zone, because `targetZone` is omitted, and the exit's never supplies it. If the entry and
54
+ * exit are bare instants — `Z` or an offset — and no `targetZone` is given, the result is `null`: an
56
55
  * offset is not a zone (CORE-4), and a day count in an unstated locality would be a guess.
56
+ * - **The offset fixes each instant; a bracketed zone only resolves a rounded one.** An offset
57
+ * written to the minute that is the bracketed zone's sub-minute offset rounded
58
+ * (`-00:45[Africa/Monrovia]`, for −00:44:30) names the instant the zone gives, as
59
+ * `Temporal.ZonedDateTime.from` reads it, on the entry and the exit alike. A zone that does
60
+ * not exist, or that disagrees with the offset, changes nothing.
57
61
  * - `enter` and `exit` are the two instants rendered in the dwell zone, so a charging record
58
62
  * shows the local times the terminal's own clock showed.
59
63
  * - `targetZone` is whatever `isValidTimeZone` accepts, which is what Temporal accepts: an IANA
@@ -92,8 +96,8 @@ export function dwellTime(entry, exit, targetZone) {
92
96
  if (zone === null) {
93
97
  return null;
94
98
  }
95
- const entryInstant = Temporal.Instant.from(entry);
96
- const exitInstant = Temporal.Instant.from(exit);
99
+ const entryInstant = instantFrom(entry);
100
+ const exitInstant = instantFrom(exit);
97
101
  if (Temporal.Instant.compare(entryInstant, exitInstant) > 0) {
98
102
  return null;
99
103
  }
@@ -0,0 +1,65 @@
1
+ import type { TimestampEvent } from "../../types/index.js";
2
+ /** Options for `estimateDrift`. */
3
+ export interface EstimateDriftOptions {
4
+ /**
5
+ * The drift allowed, as an ISO 8601 duration of exact time (a day is 24 hours; years, months and
6
+ * weeks are refused; not negative). With it, `exceedsTolerance` says whether the drift is greater
7
+ * than it.
8
+ *
9
+ * @defaultValue None. `exceedsTolerance` is `null`.
10
+ */
11
+ tolerance?: string;
12
+ }
13
+ /** What `estimateDrift` returns. */
14
+ export interface DriftReport {
15
+ /** The earliest-recorded EST's `at`, exactly as written. */
16
+ first: string;
17
+ /** The latest-recorded EST's `at`, exactly as written. */
18
+ last: string;
19
+ /**
20
+ * The drift: `last` minus `first` in exact time, hours as the largest unit; negative when it
21
+ * moved earlier.
22
+ */
23
+ drift: string;
24
+ /** The number of EST records, the first included. */
25
+ revisions: number;
26
+ /** Whether the absolute drift is greater than `tolerance`; `null` without a tolerance. */
27
+ exceedsTolerance: boolean | null;
28
+ }
29
+ /**
30
+ * Measure how far an estimate moved between its first and last revision.
31
+ *
32
+ * Schedule-reliability reporting asks how much an estimated arrival slid while it was being
33
+ * revised, and a revision far enough from the first estimate means something must be redone:
34
+ * rebooked, re-planned, renotified. The threshold is the caller's; the consequence is the
35
+ * consumer's.
36
+ *
37
+ * - Only `EST` records are read, in the order they were recorded (`recordedAt`). Two records at
38
+ * the same instant are ordered by their place in the array, the later one last — the same tie
39
+ * rule as `bestAvailable`. `PLN`, `REQ` and `ACT` records are validated and otherwise ignored.
40
+ * - `revisions` is the number of EST records, the first included.
41
+ * - `drift` is the last EST's `at` minus the first's, in exact elapsed time with hours as the
42
+ * largest unit: positive when the estimate moved later, negative when earlier. Across a
43
+ * fall-back night, 01:30 EDT to 01:30 EST is `PT1H`.
44
+ * - With `tolerance`, `exceedsTolerance` is `true` when the drift, in either direction, is
45
+ * **greater** than the tolerance; exactly the tolerance is `false`. Without it, `null`.
46
+ * - `first` and `last` echo `at` exactly as written; both are instants (`Z`/offset) or zoned
47
+ * strings compared as instants, read as `scheduleDeviation` reads them: the offset fixes the
48
+ * instant, and an offset written to the minute that is the bracketed zone's sub-minute offset
49
+ * rounded (`-00:45[Africa/Monrovia]`, for −00:44:30) names the instant the zone gives.
50
+ * Otherwise the bracket is not checked.
51
+ * - Returns `null` with fewer than two EST records — there is no drift from one sample — and on
52
+ * invalid input: any invalid event, of any class, or an invalid, negative or calendar-unit
53
+ * `tolerance`.
54
+ *
55
+ * @param events the event's timestamp records, in any order
56
+ * @param options The threshold the absolute drift is compared with
57
+ * @returns the first and last estimates, the drift, the revision count and the tolerance check (null with fewer than two EST records), or null on invalid input
58
+ *
59
+ * @example estimateDrift([{ classifier: "EST", at: "2024-06-20T08:00:00Z", recordedAt: "2024-06-01T00:00:00Z" }, { classifier: "EST", at: "2024-06-20T12:00:00Z", recordedAt: "2024-06-05T00:00:00Z" }, { classifier: "EST", at: "2024-06-20T17:00:00Z", recordedAt: "2024-06-10T00:00:00Z" }]) // { first: "2024-06-20T08:00:00Z", last: "2024-06-20T17:00:00Z", drift: "PT9H", revisions: 3, exceedsTolerance: null }
60
+ * @example estimateDrift([{ classifier: "EST", at: "2024-06-20T17:00:00Z", recordedAt: "2024-06-01T00:00:00Z" }, { classifier: "EST", at: "2024-06-20T08:00:00Z", recordedAt: "2024-06-10T00:00:00Z" }], { tolerance: "PT8H" }) // { first: "2024-06-20T17:00:00Z", last: "2024-06-20T08:00:00Z", drift: "-PT9H", revisions: 2, exceedsTolerance: true } (nine hours earlier exceeds eight)
61
+ * @example estimateDrift([{ classifier: "EST", at: "2024-06-20T08:00:00Z", recordedAt: "2024-06-01T00:00:00Z" }, { classifier: "EST", at: "2024-06-20T15:00:00Z", recordedAt: "2024-06-10T00:00:00Z" }], { tolerance: "PT8H" }) // { first: "2024-06-20T08:00:00Z", last: "2024-06-20T15:00:00Z", drift: "PT7H", revisions: 2, exceedsTolerance: false }
62
+ * @example estimateDrift([{ classifier: "EST", at: "2024-06-20T08:00:00Z", recordedAt: "2024-06-01T00:00:00Z" }]) // null (no drift from one sample)
63
+ * @example estimateDrift([{ classifier: "EST", at: "2024-06-20T08:00:00Z", recordedAt: "2024-06-01T00:00:00Z" }, { classifier: "EST", at: "2024-06-20T15:00:00Z", recordedAt: "2024-06-10T00:00:00Z" }], { tolerance: "P1W" }) // null (weeks need a reference point)
64
+ */
65
+ export declare function estimateDrift(events: TimestampEvent[], options?: EstimateDriftOptions): DriftReport | null;
@@ -0,0 +1,75 @@
1
+ import { formatHourDuration, isOptionsArgument, nonNegativeExactDurationNanoseconds, parseTimestampEvents, } from "../../internal/index.js";
2
+ /**
3
+ * Measure how far an estimate moved between its first and last revision.
4
+ *
5
+ * Schedule-reliability reporting asks how much an estimated arrival slid while it was being
6
+ * revised, and a revision far enough from the first estimate means something must be redone:
7
+ * rebooked, re-planned, renotified. The threshold is the caller's; the consequence is the
8
+ * consumer's.
9
+ *
10
+ * - Only `EST` records are read, in the order they were recorded (`recordedAt`). Two records at
11
+ * the same instant are ordered by their place in the array, the later one last — the same tie
12
+ * rule as `bestAvailable`. `PLN`, `REQ` and `ACT` records are validated and otherwise ignored.
13
+ * - `revisions` is the number of EST records, the first included.
14
+ * - `drift` is the last EST's `at` minus the first's, in exact elapsed time with hours as the
15
+ * largest unit: positive when the estimate moved later, negative when earlier. Across a
16
+ * fall-back night, 01:30 EDT to 01:30 EST is `PT1H`.
17
+ * - With `tolerance`, `exceedsTolerance` is `true` when the drift, in either direction, is
18
+ * **greater** than the tolerance; exactly the tolerance is `false`. Without it, `null`.
19
+ * - `first` and `last` echo `at` exactly as written; both are instants (`Z`/offset) or zoned
20
+ * strings compared as instants, read as `scheduleDeviation` reads them: the offset fixes the
21
+ * instant, and an offset written to the minute that is the bracketed zone's sub-minute offset
22
+ * rounded (`-00:45[Africa/Monrovia]`, for −00:44:30) names the instant the zone gives.
23
+ * Otherwise the bracket is not checked.
24
+ * - Returns `null` with fewer than two EST records — there is no drift from one sample — and on
25
+ * invalid input: any invalid event, of any class, or an invalid, negative or calendar-unit
26
+ * `tolerance`.
27
+ *
28
+ * @param events the event's timestamp records, in any order
29
+ * @param options The threshold the absolute drift is compared with
30
+ * @returns the first and last estimates, the drift, the revision count and the tolerance check (null with fewer than two EST records), or null on invalid input
31
+ *
32
+ * @example estimateDrift([{ classifier: "EST", at: "2024-06-20T08:00:00Z", recordedAt: "2024-06-01T00:00:00Z" }, { classifier: "EST", at: "2024-06-20T12:00:00Z", recordedAt: "2024-06-05T00:00:00Z" }, { classifier: "EST", at: "2024-06-20T17:00:00Z", recordedAt: "2024-06-10T00:00:00Z" }]) // { first: "2024-06-20T08:00:00Z", last: "2024-06-20T17:00:00Z", drift: "PT9H", revisions: 3, exceedsTolerance: null }
33
+ * @example estimateDrift([{ classifier: "EST", at: "2024-06-20T17:00:00Z", recordedAt: "2024-06-01T00:00:00Z" }, { classifier: "EST", at: "2024-06-20T08:00:00Z", recordedAt: "2024-06-10T00:00:00Z" }], { tolerance: "PT8H" }) // { first: "2024-06-20T17:00:00Z", last: "2024-06-20T08:00:00Z", drift: "-PT9H", revisions: 2, exceedsTolerance: true } (nine hours earlier exceeds eight)
34
+ * @example estimateDrift([{ classifier: "EST", at: "2024-06-20T08:00:00Z", recordedAt: "2024-06-01T00:00:00Z" }, { classifier: "EST", at: "2024-06-20T15:00:00Z", recordedAt: "2024-06-10T00:00:00Z" }], { tolerance: "PT8H" }) // { first: "2024-06-20T08:00:00Z", last: "2024-06-20T15:00:00Z", drift: "PT7H", revisions: 2, exceedsTolerance: false }
35
+ * @example estimateDrift([{ classifier: "EST", at: "2024-06-20T08:00:00Z", recordedAt: "2024-06-01T00:00:00Z" }]) // null (no drift from one sample)
36
+ * @example estimateDrift([{ classifier: "EST", at: "2024-06-20T08:00:00Z", recordedAt: "2024-06-01T00:00:00Z" }, { classifier: "EST", at: "2024-06-20T15:00:00Z", recordedAt: "2024-06-10T00:00:00Z" }], { tolerance: "P1W" }) // null (weeks need a reference point)
37
+ */
38
+ export function estimateDrift(events, options) {
39
+ try {
40
+ if (!isOptionsArgument(options)) {
41
+ return null;
42
+ }
43
+ const tolerance = options?.tolerance;
44
+ const toleranceNanoseconds = tolerance === undefined
45
+ ? null
46
+ : nonNegativeExactDurationNanoseconds(tolerance);
47
+ if (tolerance !== undefined && toleranceNanoseconds === null) {
48
+ return null;
49
+ }
50
+ const parsed = parseTimestampEvents(events);
51
+ if (parsed === null) {
52
+ return null;
53
+ }
54
+ const estimates = parsed.filter((event) => event.classifier === "EST");
55
+ const first = estimates[0];
56
+ const last = estimates[estimates.length - 1];
57
+ if (estimates.length < 2 || first === undefined || last === undefined) {
58
+ return null;
59
+ }
60
+ const drift = last.atNanoseconds - first.atNanoseconds;
61
+ const magnitude = drift < 0n ? -drift : drift;
62
+ return {
63
+ first: first.at,
64
+ last: last.at,
65
+ drift: `${drift < 0n ? "-" : ""}${formatHourDuration(magnitude)}`,
66
+ revisions: estimates.length,
67
+ exceedsTolerance: toleranceNanoseconds === null ? null : magnitude > toleranceNanoseconds,
68
+ };
69
+ }
70
+ catch {
71
+ // Never throws (Core Rule 3): a hostile
72
+ // argument is invalid input, not an exception.
73
+ return null;
74
+ }
75
+ }
@@ -1,2 +1,10 @@
1
+ export * from "./bestAvailable.js";
2
+ export * from "./crossingTime.js";
3
+ export * from "./cutoffAt.js";
4
+ export * from "./cutoffSchedule.js";
1
5
  export * from "./dwellTime.js";
6
+ export * from "./estimateDrift.js";
7
+ export * from "./nextDeparture.js";
8
+ export * from "./punctualityRate.js";
9
+ export * from "./scheduleDelivery.js";
2
10
  export * from "./transitTime.js";
@@ -1,2 +1,10 @@
1
+ export * from "./bestAvailable.js";
2
+ export * from "./crossingTime.js";
3
+ export * from "./cutoffAt.js";
4
+ export * from "./cutoffSchedule.js";
1
5
  export * from "./dwellTime.js";
6
+ export * from "./estimateDrift.js";
7
+ export * from "./nextDeparture.js";
8
+ export * from "./punctualityRate.js";
9
+ export * from "./scheduleDelivery.js";
2
10
  export * from "./transitTime.js";