@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.
- package/README.md +742 -21
- package/dist/calendar/calculate/bucketRange.d.ts +3 -3
- package/dist/calendar/calculate/bucketRange.js +6 -6
- package/dist/calendar/calculate/floorToZone.d.ts +5 -3
- package/dist/calendar/calculate/floorToZone.js +6 -5
- package/dist/calendar/calculate/getFiscalPeriod.d.ts +21 -8
- package/dist/calendar/calculate/getFiscalPeriod.js +9 -8
- package/dist/calendar/calculate/getIsoWeekDate.d.ts +10 -5
- package/dist/calendar/calculate/getIsoWeekDate.js +1 -5
- package/dist/calendar/calculate/getOrdinalDate.d.ts +10 -3
- package/dist/calendar/calculate/getOrdinalDate.js +2 -3
- package/dist/calendar/calculate/getQuarter.d.ts +21 -9
- package/dist/calendar/calculate/getQuarter.js +8 -12
- package/dist/calendar/hours/addOperatingTime.d.ts +53 -0
- package/dist/calendar/hours/addOperatingTime.js +59 -0
- package/dist/calendar/hours/index.d.ts +7 -0
- package/dist/calendar/hours/index.js +7 -0
- package/dist/calendar/hours/isOpenAt.d.ts +39 -0
- package/dist/calendar/hours/isOpenAt.js +44 -0
- package/dist/calendar/hours/nextCloseAt.d.ts +49 -0
- package/dist/calendar/hours/nextCloseAt.js +51 -0
- package/dist/calendar/hours/nextOpenAt.d.ts +45 -0
- package/dist/calendar/hours/nextOpenAt.js +47 -0
- package/dist/calendar/hours/operatingIntervals.d.ts +43 -0
- package/dist/calendar/hours/operatingIntervals.js +52 -0
- package/dist/calendar/hours/operatingTimeBetween.d.ts +40 -0
- package/dist/calendar/hours/operatingTimeBetween.js +49 -0
- package/dist/calendar/hours/recurringWindows.d.ts +61 -0
- package/dist/calendar/hours/recurringWindows.js +80 -0
- package/dist/calendar/index.d.ts +1 -0
- package/dist/calendar/index.js +1 -0
- package/dist/duration/calculate/durationAs.d.ts +13 -8
- package/dist/duration/calculate/durationAs.js +4 -8
- package/dist/duration/compare/compareDurations.d.ts +12 -6
- package/dist/duration/compare/compareDurations.js +3 -6
- package/dist/duration/format/formatDuration.d.ts +16 -4
- package/dist/duration/format/formatDuration.js +4 -5
- package/dist/duration/normalize/normalizeDuration.d.ts +39 -14
- package/dist/duration/normalize/normalizeDuration.js +6 -15
- package/dist/duration/parse/parseDuration.d.ts +21 -3
- package/dist/duration/parse/parseDuration.js +1 -3
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/instant/convert/classifyLocal.d.ts +1 -1
- package/dist/instant/convert/classifyLocal.js +1 -1
- package/dist/instant/convert/fromOffsetInstant.d.ts +3 -1
- package/dist/instant/convert/fromOffsetInstant.js +6 -12
- package/dist/instant/convert/resolveLocal.d.ts +12 -7
- package/dist/instant/convert/resolveLocal.js +6 -10
- package/dist/instant/convert/toOffsetInstant.d.ts +37 -1
- package/dist/instant/convert/toOffsetInstant.js +12 -28
- package/dist/intermodal/calculate/billingTimeline.d.ts +114 -0
- package/dist/intermodal/calculate/billingTimeline.js +168 -0
- package/dist/intermodal/calculate/chargeableDays.d.ts +100 -0
- package/dist/intermodal/calculate/chargeableDays.js +96 -0
- package/dist/intermodal/calculate/demurrageClock.d.ts +102 -0
- package/dist/intermodal/calculate/demurrageClock.js +140 -0
- package/dist/intermodal/calculate/freeTimeExpiry.d.ts +67 -0
- package/dist/intermodal/calculate/freeTimeExpiry.js +82 -0
- package/dist/intermodal/calculate/index.d.ts +4 -0
- package/dist/intermodal/calculate/index.js +4 -0
- package/dist/intermodal/index.d.ts +2 -0
- package/dist/intermodal/index.js +3 -0
- package/dist/internal/businessCalendar.d.ts +5 -0
- package/dist/internal/businessCalendar.js +5 -1
- package/dist/internal/cycleFieldValue.d.ts +6 -4
- package/dist/internal/cycleFieldValue.js +6 -4
- package/dist/internal/daylightTime.d.ts +33 -0
- package/dist/internal/daylightTime.js +164 -0
- package/dist/internal/durationUntilString.js +4 -3
- package/dist/internal/englishCalendarNames.js +1 -2
- package/dist/internal/epochNanoseconds.d.ts +2 -0
- package/dist/internal/epochNanoseconds.js +2 -0
- package/dist/internal/exactDuration.d.ts +37 -0
- package/dist/internal/exactDuration.js +64 -0
- package/dist/internal/exactMoment.d.ts +72 -0
- package/dist/internal/exactMoment.js +114 -0
- package/dist/internal/fiscalCalendar.d.ts +4 -3
- package/dist/internal/fiscalCalendar.js +4 -3
- package/dist/internal/formatCalendarDays.d.ts +2 -2
- package/dist/internal/formatRelativeDuration.d.ts +21 -1
- package/dist/internal/formatRelativeDuration.js +47 -7
- package/dist/internal/freeTimeLedger.d.ts +93 -0
- package/dist/internal/freeTimeLedger.js +262 -0
- package/dist/internal/index.d.ts +10 -3
- package/dist/internal/index.js +10 -3
- package/dist/internal/instantFormatOptions.js +2 -1
- package/dist/internal/instantNanoseconds.d.ts +75 -9
- package/dist/internal/instantNanoseconds.js +192 -11
- package/dist/internal/isoStringBody.d.ts +26 -0
- package/dist/internal/isoStringBody.js +22 -2
- package/dist/internal/joinDateTimeConnector.d.ts +1 -1
- package/dist/internal/monthGridWeekRow.d.ts +2 -1
- package/dist/internal/monthGridWeekRow.js +2 -1
- package/dist/internal/normalizeTimeZone.d.ts +2 -2
- package/dist/internal/normalizeTimeZone.js +2 -2
- package/dist/internal/operatingSchedule.d.ts +129 -0
- package/dist/internal/operatingSchedule.js +668 -0
- package/dist/internal/optionOrDefault.d.ts +18 -0
- package/dist/internal/optionOrDefault.js +20 -0
- package/dist/internal/patternToken.d.ts +2 -2
- package/dist/internal/patternToken.js +28 -13
- package/dist/internal/plainDateUntil.js +10 -6
- package/dist/internal/punctuality.d.ts +38 -0
- package/dist/internal/punctuality.js +59 -0
- package/dist/internal/readDateTimeFormatOptions.d.ts +30 -0
- package/dist/internal/readDateTimeFormatOptions.js +93 -0
- package/dist/internal/resolveDurationRelativeTo.d.ts +4 -0
- package/dist/internal/resolveDurationRelativeTo.js +11 -1
- package/dist/internal/resolveRelativeRounding.d.ts +17 -6
- package/dist/internal/resolveRelativeRounding.js +27 -7
- package/dist/internal/resolveRelativeUnit.d.ts +30 -0
- package/dist/internal/resolveRelativeUnit.js +40 -0
- package/dist/internal/splitStep.d.ts +24 -1
- package/dist/internal/splitStep.js +34 -2
- package/dist/internal/startOrEndOfZoned.js +2 -3
- package/dist/internal/temporalCompat/capabilities.d.ts +26 -0
- package/dist/internal/temporalCompat/capabilities.js +35 -3
- package/dist/internal/temporalCompat/fieldSearch.js +1 -1
- package/dist/internal/temporalCompat/index.d.ts +1 -1
- package/dist/internal/temporalCompat/index.js +1 -1
- package/dist/internal/temporalCompat/repros.d.ts +1 -1
- package/dist/internal/temporalCompat/repros.js +157 -0
- package/dist/internal/timestampEvents.d.ts +32 -0
- package/dist/internal/timestampEvents.js +76 -0
- package/dist/internal/utcZonedDateTime.d.ts +5 -2
- package/dist/internal/utcZonedDateTime.js +8 -5
- package/dist/internal/wallClockAtOffset.d.ts +22 -0
- package/dist/internal/wallClockAtOffset.js +26 -0
- package/dist/internal/zonedBucket.js +8 -6
- package/dist/internal/zonedLocalDates.js +1 -1
- package/dist/internal/zonedTransitionSearch.d.ts +27 -0
- package/dist/internal/zonedTransitionSearch.js +218 -0
- package/dist/internal/zonedWallClock.d.ts +21 -7
- package/dist/internal/zonedWallClock.js +87 -18
- package/dist/internal/zonedWallClockDifference.js +5 -4
- package/dist/internal/zonedWallClockOperations.d.ts +26 -13
- package/dist/internal/zonedWallClockOperations.js +87 -34
- package/dist/interval/validate/isValidInterval.d.ts +6 -3
- package/dist/interval/validate/isValidInterval.js +6 -3
- package/dist/plain/calculate/addDate.d.ts +11 -8
- package/dist/plain/calculate/addDate.js +5 -8
- package/dist/plain/calculate/addDateTime.d.ts +7 -4
- package/dist/plain/calculate/addDateTime.js +1 -4
- package/dist/plain/calculate/cycleDate.d.ts +16 -7
- package/dist/plain/calculate/cycleDate.js +3 -7
- package/dist/plain/calculate/cycleDateTime.d.ts +14 -4
- package/dist/plain/calculate/cycleDateTime.js +1 -4
- package/dist/plain/calculate/cycleTime.d.ts +10 -5
- package/dist/plain/calculate/cycleTime.js +3 -5
- package/dist/plain/calculate/diffDate.d.ts +1 -1
- package/dist/plain/calculate/diffDate.js +1 -1
- package/dist/plain/calculate/diffDateAsDuration.d.ts +1 -1
- package/dist/plain/calculate/diffDateAsDuration.js +1 -1
- package/dist/plain/calculate/diffDateTime.d.ts +1 -1
- package/dist/plain/calculate/diffDateTime.js +1 -1
- package/dist/plain/calculate/diffDateTimeAsDuration.d.ts +1 -1
- package/dist/plain/calculate/diffDateTimeAsDuration.js +1 -1
- package/dist/plain/calculate/diffTime.d.ts +1 -1
- package/dist/plain/calculate/diffTime.js +1 -1
- package/dist/plain/calculate/endOfDate.d.ts +8 -3
- package/dist/plain/calculate/endOfDate.js +1 -3
- package/dist/plain/calculate/endOfDateTime.d.ts +15 -5
- package/dist/plain/calculate/endOfDateTime.js +1 -5
- package/dist/plain/calculate/endOfTime.d.ts +8 -2
- package/dist/plain/calculate/endOfTime.js +1 -2
- package/dist/plain/calculate/getLocaleWeekYear.d.ts +16 -9
- package/dist/plain/calculate/getLocaleWeekYear.js +9 -9
- package/dist/plain/calculate/getWeekOfMonth.d.ts +7 -4
- package/dist/plain/calculate/getWeekOfMonth.js +7 -4
- package/dist/plain/calculate/getWeeksInLocaleWeekYear.d.ts +13 -6
- package/dist/plain/calculate/getWeeksInLocaleWeekYear.js +6 -6
- package/dist/plain/calculate/getWeeksInMonth.d.ts +5 -2
- package/dist/plain/calculate/getWeeksInMonth.js +5 -2
- package/dist/plain/calculate/nextWeekday.d.ts +7 -3
- package/dist/plain/calculate/nextWeekday.js +1 -3
- package/dist/plain/calculate/previousWeekday.d.ts +7 -3
- package/dist/plain/calculate/previousWeekday.js +1 -3
- package/dist/plain/calculate/roundDate.d.ts +20 -7
- package/dist/plain/calculate/roundDate.js +3 -10
- package/dist/plain/calculate/roundDateTime.d.ts +22 -8
- package/dist/plain/calculate/roundDateTime.js +3 -11
- package/dist/plain/calculate/roundTime.d.ts +20 -4
- package/dist/plain/calculate/roundTime.js +3 -7
- package/dist/plain/calculate/setDate.d.ts +7 -5
- package/dist/plain/calculate/setDate.js +1 -5
- package/dist/plain/calculate/setDateTime.d.ts +8 -5
- package/dist/plain/calculate/setDateTime.js +1 -5
- package/dist/plain/calculate/setTime.d.ts +10 -6
- package/dist/plain/calculate/setTime.js +4 -6
- package/dist/plain/calculate/startOfDate.d.ts +8 -2
- package/dist/plain/calculate/startOfDate.js +1 -2
- package/dist/plain/calculate/startOfDateTime.d.ts +15 -2
- package/dist/plain/calculate/startOfDateTime.js +1 -2
- package/dist/plain/calculate/startOfTime.d.ts +8 -1
- package/dist/plain/calculate/startOfTime.js +1 -1
- package/dist/plain/calculate/subtractDate.d.ts +7 -4
- package/dist/plain/calculate/subtractDate.js +1 -4
- package/dist/plain/calculate/subtractDateTime.d.ts +7 -4
- package/dist/plain/calculate/subtractDateTime.js +1 -4
- package/dist/plain/compare/areDateTimesEqualBy.d.ts +13 -5
- package/dist/plain/compare/areDateTimesEqualBy.js +6 -5
- package/dist/plain/compare/areDatesEqualBy.d.ts +15 -6
- package/dist/plain/compare/areDatesEqualBy.js +8 -6
- package/dist/plain/compare/isBetweenDate.d.ts +13 -2
- package/dist/plain/compare/isBetweenDate.js +4 -4
- package/dist/plain/compare/isBetweenDateTime.d.ts +13 -2
- package/dist/plain/compare/isBetweenDateTime.js +4 -4
- package/dist/plain/compare/isBetweenTime.d.ts +13 -2
- package/dist/plain/compare/isBetweenTime.js +4 -4
- package/dist/plain/compare/isRelativeDay.d.ts +1 -1
- package/dist/plain/compare/isRelativeDay.js +1 -1
- package/dist/plain/compare/isThisUnit.d.ts +1 -1
- package/dist/plain/compare/isThisUnit.js +1 -1
- package/dist/plain/format/formatCalendar.d.ts +21 -14
- package/dist/plain/format/formatCalendar.js +21 -16
- package/dist/plain/format/formatDate.js +5 -3
- package/dist/plain/format/formatDateRange.js +4 -2
- package/dist/plain/format/formatDateTime.js +4 -2
- package/dist/plain/format/formatDateTimeRange.js +4 -2
- package/dist/plain/format/formatDateTimeToParts.d.ts +15 -4
- package/dist/plain/format/formatDateTimeToParts.js +10 -6
- package/dist/plain/format/formatDateToParts.d.ts +13 -2
- package/dist/plain/format/formatDateToParts.js +8 -4
- package/dist/plain/format/formatRelativeDate.d.ts +16 -3
- package/dist/plain/format/formatRelativeDate.js +26 -15
- package/dist/plain/format/formatRelativeDateTime.d.ts +16 -3
- package/dist/plain/format/formatRelativeDateTime.js +8 -5
- package/dist/plain/format/formatRelativeTime.d.ts +16 -3
- package/dist/plain/format/formatRelativeTime.js +21 -13
- package/dist/plain/format/formatTime.js +4 -2
- package/dist/plain/interval/intervalDifferenceDate.d.ts +9 -0
- package/dist/plain/interval/intervalDifferenceDateTime.d.ts +9 -0
- package/dist/plain/interval/intervalDifferenceTime.d.ts +9 -0
- package/dist/plain/interval/intervalDivideEquallyDate.d.ts +19 -4
- package/dist/plain/interval/intervalDivideEquallyDate.js +3 -4
- package/dist/plain/interval/intervalDivideEquallyDateTime.d.ts +19 -4
- package/dist/plain/interval/intervalDivideEquallyDateTime.js +3 -4
- package/dist/plain/interval/intervalDivideEquallyTime.d.ts +19 -4
- package/dist/plain/interval/intervalDivideEquallyTime.js +3 -4
- package/dist/plain/interval/intervalFromDurationDate.d.ts +16 -3
- package/dist/plain/interval/intervalFromDurationDate.js +1 -3
- package/dist/plain/interval/intervalFromDurationDateTime.d.ts +16 -3
- package/dist/plain/interval/intervalFromDurationDateTime.js +1 -3
- package/dist/plain/interval/intervalFromDurationTime.d.ts +9 -0
- package/dist/plain/interval/intervalIntersectionDate.d.ts +9 -0
- package/dist/plain/interval/intervalIntersectionDateTime.d.ts +9 -0
- package/dist/plain/interval/intervalIntersectionTime.d.ts +9 -0
- package/dist/plain/interval/intervalSplitAtDate.d.ts +11 -0
- package/dist/plain/interval/intervalSplitAtDate.js +2 -0
- package/dist/plain/interval/intervalSplitAtDateTime.d.ts +11 -0
- package/dist/plain/interval/intervalSplitAtDateTime.js +2 -0
- package/dist/plain/interval/intervalSplitAtTime.d.ts +11 -0
- package/dist/plain/interval/intervalSplitAtTime.js +2 -0
- package/dist/plain/interval/intervalUnionDate.d.ts +9 -0
- package/dist/plain/interval/intervalUnionDateTime.d.ts +9 -0
- package/dist/plain/interval/intervalUnionTime.d.ts +9 -0
- package/dist/plain/interval/intervalXorAllDate.d.ts +9 -0
- package/dist/plain/interval/intervalXorAllDateTime.d.ts +9 -0
- package/dist/plain/interval/intervalXorAllTime.d.ts +9 -0
- package/dist/plain/interval/intervalXorDate.d.ts +9 -0
- package/dist/plain/interval/intervalXorDateTime.d.ts +9 -0
- package/dist/plain/interval/intervalXorTime.d.ts +9 -0
- package/dist/plain/interval/mergeIntervalsDate.d.ts +9 -0
- package/dist/plain/interval/mergeIntervalsDateTime.d.ts +9 -0
- package/dist/plain/interval/mergeIntervalsTime.d.ts +9 -0
- package/dist/plain/interval/splitIntervalByUnitDate.d.ts +23 -7
- package/dist/plain/interval/splitIntervalByUnitDate.js +7 -7
- package/dist/plain/interval/splitIntervalByUnitDateTime.d.ts +22 -6
- package/dist/plain/interval/splitIntervalByUnitDateTime.js +6 -6
- package/dist/plain/interval/splitIntervalByUnitTime.d.ts +17 -4
- package/dist/plain/interval/splitIntervalByUnitTime.js +1 -4
- package/dist/plain/map/mapDatesInRange.d.ts +8 -4
- package/dist/plain/map/mapDatesInRange.js +1 -4
- package/dist/plain/parse/parseDateTimeWithPattern.d.ts +10 -7
- package/dist/plain/parse/parseDateTimeWithPattern.js +10 -7
- package/dist/plain/parse/parseDateWithPattern.d.ts +10 -7
- package/dist/plain/parse/parseDateWithPattern.js +10 -7
- package/dist/plain/parse/parseTimeWithPattern.d.ts +10 -7
- package/dist/plain/parse/parseTimeWithPattern.js +10 -7
- package/dist/plain/parse/parseUnitFromDate.d.ts +11 -3
- package/dist/plain/parse/parseUnitFromDate.js +3 -3
- package/dist/plain/parse/parseUnitFromDateTime.d.ts +11 -3
- package/dist/plain/parse/parseUnitFromDateTime.js +3 -3
- package/dist/plain/parse/parseWeekFromDate.d.ts +10 -6
- package/dist/plain/parse/parseWeekFromDate.js +2 -6
- package/dist/plain/parse/parseWeekFromDateTime.d.ts +10 -6
- package/dist/plain/parse/parseWeekFromDateTime.js +2 -6
- package/dist/plain/validate/isValidDateRange.d.ts +19 -4
- package/dist/plain/validate/isValidDateRange.js +1 -4
- package/dist/plain/validate/isValidDateTimeRange.d.ts +20 -5
- package/dist/plain/validate/isValidDateTimeRange.js +2 -5
- package/dist/plain/validate/isValidTimeRange.d.ts +20 -5
- package/dist/plain/validate/isValidTimeRange.js +2 -5
- package/dist/precision/convert/fromExcelSerial.d.ts +10 -4
- package/dist/precision/convert/fromExcelSerial.js +4 -5
- package/dist/precision/convert/fromNanoseconds.d.ts +1 -1
- package/dist/precision/convert/fromNanoseconds.js +1 -1
- package/dist/precision/convert/toExcelSerial.d.ts +9 -3
- package/dist/precision/convert/toExcelSerial.js +3 -4
- package/dist/precision/convert/toNanoseconds.d.ts +11 -6
- package/dist/precision/convert/toNanoseconds.js +11 -6
- package/dist/precision/validate/isValidInstant.d.ts +12 -3
- package/dist/precision/validate/isValidInstant.js +12 -3
- package/dist/span/calculate/spanMs.d.ts +10 -4
- package/dist/span/calculate/spanMs.js +10 -4
- package/dist/span/calculate/spanNs.d.ts +10 -4
- package/dist/span/calculate/spanNs.js +10 -4
- package/dist/span/validate/isValidSpan.d.ts +8 -3
- package/dist/span/validate/isValidSpan.js +8 -3
- package/dist/transport/calculate/bestAvailable.d.ts +47 -0
- package/dist/transport/calculate/bestAvailable.js +76 -0
- package/dist/transport/calculate/crossingTime.d.ts +58 -0
- package/dist/transport/calculate/crossingTime.js +76 -0
- package/dist/transport/calculate/cutoffAt.d.ts +90 -0
- package/dist/transport/calculate/cutoffAt.js +209 -0
- package/dist/transport/calculate/cutoffSchedule.d.ts +70 -0
- package/dist/transport/calculate/cutoffSchedule.js +71 -0
- package/dist/transport/calculate/dwellTime.d.ts +81 -0
- package/dist/transport/calculate/dwellTime.js +130 -0
- package/dist/transport/calculate/estimateDrift.d.ts +65 -0
- package/dist/transport/calculate/estimateDrift.js +75 -0
- package/dist/transport/calculate/index.d.ts +10 -0
- package/dist/transport/calculate/index.js +10 -0
- package/dist/transport/calculate/nextDeparture.d.ts +78 -0
- package/dist/transport/calculate/nextDeparture.js +131 -0
- package/dist/transport/calculate/punctualityRate.d.ts +42 -0
- package/dist/transport/calculate/punctualityRate.js +59 -0
- package/dist/transport/calculate/scheduleDelivery.d.ts +150 -0
- package/dist/transport/calculate/scheduleDelivery.js +300 -0
- package/dist/transport/calculate/transitTime.d.ts +71 -0
- package/dist/transport/calculate/transitTime.js +101 -0
- package/dist/transport/compare/classifyPunctuality.d.ts +46 -0
- package/dist/transport/compare/classifyPunctuality.js +64 -0
- package/dist/transport/compare/index.d.ts +4 -0
- package/dist/transport/compare/index.js +4 -0
- package/dist/transport/compare/isPastCutoff.d.ts +33 -0
- package/dist/transport/compare/isPastCutoff.js +48 -0
- package/dist/transport/compare/scheduleDeviation.d.ts +37 -0
- package/dist/transport/compare/scheduleDeviation.js +53 -0
- package/dist/transport/compare/timeToCutoff.d.ts +31 -0
- package/dist/transport/compare/timeToCutoff.js +47 -0
- package/dist/transport/convert/etaAtZone.d.ts +43 -0
- package/dist/transport/convert/etaAtZone.js +58 -0
- package/dist/transport/convert/index.d.ts +1 -0
- package/dist/transport/convert/index.js +1 -0
- package/dist/transport/index.d.ts +4 -0
- package/dist/transport/index.js +5 -0
- package/dist/types/business-calendar.d.ts +19 -14
- package/dist/types/calendar-options.d.ts +15 -3
- package/dist/types/date-cycle-field.d.ts +5 -0
- package/dist/types/date-duration-unit.d.ts +4 -0
- package/dist/types/date-time-cycle-field.d.ts +4 -0
- package/dist/types/date-time-duration-units.d.ts +4 -0
- package/dist/types/date-time-unit.d.ts +4 -0
- package/dist/types/date-unit.d.ts +4 -0
- package/dist/types/disambiguation.d.ts +8 -0
- package/dist/types/duration-relative-to.d.ts +8 -0
- package/dist/types/duration-string-options.d.ts +28 -0
- package/dist/types/fiscal-calendar.d.ts +1 -1
- package/dist/types/fractional-digit.d.ts +5 -0
- package/dist/types/free-time-options.d.ts +44 -0
- package/dist/types/index.d.ts +3 -1
- package/dist/types/index.js +3 -1
- package/dist/types/interval.d.ts +8 -1
- package/dist/types/offset.d.ts +9 -0
- package/dist/types/operating-schedule.d.ts +71 -0
- package/dist/types/operating-schedule.js +0 -0
- package/dist/types/overflow.d.ts +6 -0
- package/dist/types/relative-rounding-method.d.ts +6 -0
- package/dist/types/relative-time-options.d.ts +33 -5
- package/dist/types/rounding-options.d.ts +27 -0
- package/dist/types/time-cycle-field.d.ts +4 -0
- package/dist/types/time-duration-unit.d.ts +4 -0
- package/dist/types/time-unit.d.ts +4 -0
- package/dist/types/transport-timestamps.d.ts +54 -0
- package/dist/types/transport-timestamps.js +0 -0
- package/dist/unix/calculate/addUnix.d.ts +19 -5
- package/dist/unix/calculate/addUnix.js +1 -5
- package/dist/unix/calculate/diffUnix.d.ts +13 -3
- package/dist/unix/calculate/diffUnix.js +1 -3
- package/dist/unix/calculate/diffUnixAsDuration.d.ts +13 -3
- package/dist/unix/calculate/diffUnixAsDuration.js +1 -3
- package/dist/unix/calculate/endOfQuarterForUnix.d.ts +13 -3
- package/dist/unix/calculate/endOfQuarterForUnix.js +1 -3
- package/dist/unix/calculate/endOfUnix.d.ts +20 -4
- package/dist/unix/calculate/endOfUnix.js +1 -4
- package/dist/unix/calculate/isBetweenUnix.d.ts +26 -4
- package/dist/unix/calculate/isBetweenUnix.js +4 -6
- package/dist/unix/calculate/roundUnix.d.ts +31 -3
- package/dist/unix/calculate/roundUnix.js +3 -6
- package/dist/unix/calculate/setUnix.d.ts +35 -9
- package/dist/unix/calculate/setUnix.js +4 -13
- package/dist/unix/calculate/startOfQuarterForUnix.d.ts +13 -3
- package/dist/unix/calculate/startOfQuarterForUnix.js +1 -3
- package/dist/unix/calculate/startOfUnix.d.ts +20 -4
- package/dist/unix/calculate/startOfUnix.js +1 -4
- package/dist/unix/calculate/subtractUnix.d.ts +19 -5
- package/dist/unix/calculate/subtractUnix.js +1 -5
- package/dist/unix/compare/areUnixEqual.d.ts +7 -1
- package/dist/unix/compare/areUnixEqual.js +1 -1
- package/dist/unix/compare/areUnixEqualBy.d.ts +24 -7
- package/dist/unix/compare/areUnixEqualBy.js +13 -9
- package/dist/unix/compare/isAfterUnix.d.ts +7 -1
- package/dist/unix/compare/isAfterUnix.js +1 -1
- package/dist/unix/compare/isBeforeUnix.d.ts +7 -1
- package/dist/unix/compare/isBeforeUnix.js +1 -1
- package/dist/unix/convert/convertUnixToPlainDate.d.ts +14 -4
- package/dist/unix/convert/convertUnixToPlainDate.js +2 -4
- package/dist/unix/convert/convertUnixToPlainDateTime.d.ts +14 -4
- package/dist/unix/convert/convertUnixToPlainDateTime.js +2 -4
- package/dist/unix/convert/convertUnixToPlainTime.d.ts +14 -4
- package/dist/unix/convert/convertUnixToPlainTime.js +2 -4
- package/dist/unix/convert/convertUnixToUtc.d.ts +9 -4
- package/dist/unix/convert/convertUnixToUtc.js +3 -4
- package/dist/unix/convert/convertUnixToZoned.d.ts +10 -5
- package/dist/unix/convert/convertUnixToZoned.js +4 -5
- package/dist/unix/format/formatCalendarUnix.d.ts +27 -19
- package/dist/unix/format/formatCalendarUnix.js +4 -5
- package/dist/unix/format/formatRelativeUnix.d.ts +54 -5
- package/dist/unix/format/formatRelativeUnix.js +3 -5
- package/dist/unix/format/formatUnix.d.ts +24 -6
- package/dist/unix/format/formatUnix.js +8 -7
- package/dist/unix/get/getUnixNow.d.ts +8 -3
- package/dist/unix/get/getUnixNow.js +1 -3
- package/dist/unix/interval/intervalCountUnix.d.ts +14 -5
- package/dist/unix/interval/intervalCountUnix.js +2 -5
- package/dist/unix/interval/intervalDifferenceUnix.d.ts +6 -0
- package/dist/unix/interval/intervalDivideEquallyUnix.d.ts +18 -4
- package/dist/unix/interval/intervalDivideEquallyUnix.js +5 -4
- package/dist/unix/interval/intervalFromDurationUnix.d.ts +33 -5
- package/dist/unix/interval/intervalFromDurationUnix.js +6 -5
- package/dist/unix/interval/intervalIntersectionUnix.d.ts +6 -0
- package/dist/unix/interval/intervalLengthUnix.d.ts +16 -6
- package/dist/unix/interval/intervalLengthUnix.js +4 -6
- package/dist/unix/interval/intervalOverlappingDaysUnix.d.ts +13 -3
- package/dist/unix/interval/intervalOverlappingDaysUnix.js +1 -3
- package/dist/unix/interval/intervalSplitAtUnix.d.ts +8 -0
- package/dist/unix/interval/intervalSplitAtUnix.js +2 -0
- package/dist/unix/interval/intervalUnionUnix.d.ts +6 -0
- package/dist/unix/interval/intervalXorAllUnix.d.ts +6 -0
- package/dist/unix/interval/intervalXorUnix.d.ts +6 -0
- package/dist/unix/interval/mergeIntervalsUnix.d.ts +6 -0
- package/dist/unix/interval/splitIntervalByUnitUnix.d.ts +42 -11
- package/dist/unix/interval/splitIntervalByUnitUnix.js +21 -16
- package/dist/unix/parse/parseDateFromUnix.d.ts +13 -2
- package/dist/unix/parse/parseDateFromUnix.js +1 -2
- package/dist/unix/parse/parseDayFromUnix.d.ts +14 -2
- package/dist/unix/parse/parseDayFromUnix.js +2 -2
- package/dist/unix/parse/parseDayOfWeekFromUnix.d.ts +13 -1
- package/dist/unix/parse/parseDayOfWeekFromUnix.js +1 -1
- package/dist/unix/parse/parseHourFromUnix.d.ts +14 -2
- package/dist/unix/parse/parseHourFromUnix.js +2 -2
- package/dist/unix/parse/parseMicrosecondFromUnix.d.ts +14 -2
- package/dist/unix/parse/parseMicrosecondFromUnix.js +2 -2
- package/dist/unix/parse/parseMillisecondFromUnix.d.ts +14 -2
- package/dist/unix/parse/parseMillisecondFromUnix.js +2 -2
- package/dist/unix/parse/parseMinuteFromUnix.d.ts +14 -2
- package/dist/unix/parse/parseMinuteFromUnix.js +2 -2
- package/dist/unix/parse/parseMonthFromUnix.d.ts +14 -2
- package/dist/unix/parse/parseMonthFromUnix.js +2 -2
- package/dist/unix/parse/parseNanosecondFromUnix.d.ts +14 -2
- package/dist/unix/parse/parseNanosecondFromUnix.js +2 -2
- package/dist/unix/parse/parseSecondFromUnix.d.ts +14 -2
- package/dist/unix/parse/parseSecondFromUnix.js +2 -2
- package/dist/unix/parse/parseTimeFromUnix.d.ts +13 -2
- package/dist/unix/parse/parseTimeFromUnix.js +1 -2
- package/dist/unix/parse/parseUnitFromUnix.d.ts +22 -3
- package/dist/unix/parse/parseUnitFromUnix.js +2 -3
- package/dist/unix/parse/parseWeekFromUnix.d.ts +23 -7
- package/dist/unix/parse/parseWeekFromUnix.js +3 -7
- package/dist/unix/parse/parseYearFromUnix.d.ts +14 -2
- package/dist/unix/parse/parseYearFromUnix.js +2 -2
- package/dist/unix/validate/isValidUnixRange.d.ts +20 -4
- package/dist/unix/validate/isValidUnixRange.js +1 -4
- package/dist/utc/calculate/addUtc.d.ts +7 -4
- package/dist/utc/calculate/addUtc.js +1 -4
- package/dist/utc/calculate/diffUtc.d.ts +1 -1
- package/dist/utc/calculate/diffUtc.js +1 -1
- package/dist/utc/calculate/diffUtcAsDuration.d.ts +1 -1
- package/dist/utc/calculate/diffUtcAsDuration.js +1 -1
- package/dist/utc/calculate/endOfUtc.d.ts +16 -3
- package/dist/utc/calculate/endOfUtc.js +2 -3
- package/dist/utc/calculate/isBetweenUtc.d.ts +13 -2
- package/dist/utc/calculate/isBetweenUtc.js +4 -4
- package/dist/utc/calculate/roundUtc.d.ts +26 -9
- package/dist/utc/calculate/roundUtc.js +3 -12
- package/dist/utc/calculate/setUtc.d.ts +7 -4
- package/dist/utc/calculate/setUtc.js +1 -4
- package/dist/utc/calculate/startOfUtc.d.ts +15 -2
- package/dist/utc/calculate/startOfUtc.js +1 -2
- package/dist/utc/calculate/subtractUtc.d.ts +7 -4
- package/dist/utc/calculate/subtractUtc.js +1 -4
- package/dist/utc/compare/areUtcEqualBy.d.ts +9 -3
- package/dist/utc/compare/areUtcEqualBy.js +2 -3
- package/dist/utc/convert/convertUtcToPlainDate.d.ts +8 -3
- package/dist/utc/convert/convertUtcToPlainDate.js +5 -6
- package/dist/utc/convert/convertUtcToPlainDateTime.d.ts +8 -3
- package/dist/utc/convert/convertUtcToPlainDateTime.js +5 -6
- package/dist/utc/convert/convertUtcToPlainTime.d.ts +8 -3
- package/dist/utc/convert/convertUtcToPlainTime.js +5 -6
- package/dist/utc/convert/convertUtcToUnix.d.ts +9 -4
- package/dist/utc/convert/convertUtcToUnix.js +3 -4
- package/dist/utc/convert/convertUtcToZoned.d.ts +1 -1
- package/dist/utc/convert/convertUtcToZoned.js +1 -1
- package/dist/utc/format/formatCalendarUtc.d.ts +19 -8
- package/dist/utc/format/formatCalendarUtc.js +8 -6
- package/dist/utc/format/formatHttp.d.ts +1 -1
- package/dist/utc/format/formatHttp.js +1 -1
- package/dist/utc/format/formatRelativeUtc.d.ts +30 -10
- package/dist/utc/format/formatRelativeUtc.js +9 -11
- package/dist/utc/format/formatUtc.d.ts +17 -15
- package/dist/utc/format/formatUtc.js +8 -8
- package/dist/utc/interval/intervalDifferenceUtc.d.ts +6 -0
- package/dist/utc/interval/intervalDivideEquallyUtc.d.ts +18 -4
- package/dist/utc/interval/intervalDivideEquallyUtc.js +5 -4
- package/dist/utc/interval/intervalFromDurationUtc.d.ts +13 -3
- package/dist/utc/interval/intervalFromDurationUtc.js +1 -3
- package/dist/utc/interval/intervalIntersectionUtc.d.ts +6 -0
- package/dist/utc/interval/intervalSplitAtUtc.d.ts +8 -0
- package/dist/utc/interval/intervalSplitAtUtc.js +2 -0
- package/dist/utc/interval/intervalUnionUtc.d.ts +6 -0
- package/dist/utc/interval/intervalXorAllUtc.d.ts +6 -0
- package/dist/utc/interval/intervalXorUtc.d.ts +6 -0
- package/dist/utc/interval/mergeIntervalsUtc.d.ts +6 -0
- package/dist/utc/interval/splitIntervalByUnitUtc.d.ts +19 -6
- package/dist/utc/interval/splitIntervalByUnitUtc.js +6 -6
- package/dist/utc/parse/parseDateFromUtc.d.ts +7 -3
- package/dist/utc/parse/parseDateFromUtc.js +1 -3
- package/dist/utc/parse/parseDayFromUtc.d.ts +7 -3
- package/dist/utc/parse/parseDayFromUtc.js +1 -3
- package/dist/utc/parse/parseDayOfWeekFromUtc.d.ts +7 -3
- package/dist/utc/parse/parseDayOfWeekFromUtc.js +4 -6
- package/dist/utc/parse/parseHourFromUtc.d.ts +7 -3
- package/dist/utc/parse/parseHourFromUtc.js +1 -3
- package/dist/utc/parse/parseHttp.d.ts +1 -1
- package/dist/utc/parse/parseHttp.js +1 -1
- package/dist/utc/parse/parseMicrosecondFromUtc.d.ts +7 -3
- package/dist/utc/parse/parseMicrosecondFromUtc.js +1 -3
- package/dist/utc/parse/parseMillisecondFromUtc.d.ts +7 -3
- package/dist/utc/parse/parseMillisecondFromUtc.js +1 -3
- package/dist/utc/parse/parseMinuteFromUtc.d.ts +7 -3
- package/dist/utc/parse/parseMinuteFromUtc.js +1 -3
- package/dist/utc/parse/parseMonthFromUtc.d.ts +7 -3
- package/dist/utc/parse/parseMonthFromUtc.js +1 -3
- package/dist/utc/parse/parseNanosecondFromUtc.d.ts +7 -3
- package/dist/utc/parse/parseNanosecondFromUtc.js +1 -3
- package/dist/utc/parse/parseSecondFromUtc.d.ts +7 -3
- package/dist/utc/parse/parseSecondFromUtc.js +1 -3
- package/dist/utc/parse/parseTimeFromUtc.d.ts +8 -3
- package/dist/utc/parse/parseTimeFromUtc.js +5 -6
- package/dist/utc/parse/parseUnitFromUtc.d.ts +17 -5
- package/dist/utc/parse/parseUnitFromUtc.js +6 -8
- package/dist/utc/parse/parseWeekFromUtc.d.ts +18 -10
- package/dist/utc/parse/parseWeekFromUtc.js +7 -13
- package/dist/utc/parse/parseYearFromUtc.d.ts +7 -3
- package/dist/utc/parse/parseYearFromUtc.js +1 -3
- package/dist/utc/validate/isValidUtcRange.d.ts +16 -5
- package/dist/utc/validate/isValidUtcRange.js +2 -5
- package/dist/zoned/calculate/addZoned.d.ts +20 -10
- package/dist/zoned/calculate/addZoned.js +6 -13
- package/dist/zoned/calculate/cycleZoned.d.ts +33 -8
- package/dist/zoned/calculate/cycleZoned.js +1 -8
- package/dist/zoned/calculate/diffZoned.d.ts +1 -1
- package/dist/zoned/calculate/diffZoned.js +1 -1
- package/dist/zoned/calculate/diffZonedAsDuration.d.ts +1 -1
- package/dist/zoned/calculate/diffZonedAsDuration.js +1 -1
- package/dist/zoned/calculate/endOfQuarterForZoned.d.ts +9 -2
- package/dist/zoned/calculate/endOfQuarterForZoned.js +4 -5
- package/dist/zoned/calculate/endOfZoned.d.ts +16 -3
- package/dist/zoned/calculate/endOfZoned.js +2 -3
- package/dist/zoned/calculate/getLocaleZonedEndOfWeek.d.ts +10 -3
- package/dist/zoned/calculate/getLocaleZonedEndOfWeek.js +5 -6
- package/dist/zoned/calculate/getLocaleZonedStartOfWeek.d.ts +7 -1
- package/dist/zoned/calculate/getLocaleZonedStartOfWeek.js +3 -4
- package/dist/zoned/calculate/roundZoned.d.ts +21 -4
- package/dist/zoned/calculate/roundZoned.js +3 -7
- package/dist/zoned/calculate/setZoned.d.ts +25 -8
- package/dist/zoned/calculate/setZoned.js +4 -12
- package/dist/zoned/calculate/startOfQuarterForZoned.d.ts +7 -2
- package/dist/zoned/calculate/startOfQuarterForZoned.js +3 -5
- package/dist/zoned/calculate/startOfZoned.d.ts +15 -3
- package/dist/zoned/calculate/startOfZoned.js +1 -3
- package/dist/zoned/calculate/subtractZoned.d.ts +20 -10
- package/dist/zoned/calculate/subtractZoned.js +6 -13
- package/dist/zoned/compare/areZonedEqualBy.d.ts +14 -5
- package/dist/zoned/compare/areZonedEqualBy.js +7 -5
- package/dist/zoned/compare/isBetweenZoned.d.ts +13 -1
- package/dist/zoned/compare/isBetweenZoned.js +4 -3
- package/dist/zoned/compare/isInDaylightSaving.d.ts +38 -11
- package/dist/zoned/compare/isInDaylightSaving.js +40 -44
- package/dist/zoned/convert/convertPlainDateTimeToZoned.d.ts +18 -5
- package/dist/zoned/convert/convertPlainDateTimeToZoned.js +6 -11
- package/dist/zoned/convert/convertZonedToUnix.d.ts +9 -4
- package/dist/zoned/convert/convertZonedToUnix.js +2 -4
- package/dist/zoned/convert/convertZonedToZoned.d.ts +1 -1
- package/dist/zoned/convert/convertZonedToZoned.js +1 -1
- package/dist/zoned/format/formatCalendarZoned.d.ts +18 -12
- package/dist/zoned/format/formatCalendarZoned.js +13 -9
- package/dist/zoned/format/formatRelativeZoned.d.ts +41 -12
- package/dist/zoned/format/formatRelativeZoned.js +7 -4
- package/dist/zoned/format/formatRfc2822.d.ts +2 -2
- package/dist/zoned/format/formatRfc2822.js +2 -2
- package/dist/zoned/format/formatRfc3339.d.ts +2 -3
- package/dist/zoned/format/formatRfc3339.js +2 -3
- package/dist/zoned/format/formatTimeZoneName.d.ts +12 -3
- package/dist/zoned/format/formatTimeZoneName.js +5 -4
- package/dist/zoned/format/formatZonedDateTime.js +2 -1
- package/dist/zoned/format/formatZonedRange.js +2 -1
- package/dist/zoned/format/formatZonedToParts.d.ts +15 -4
- package/dist/zoned/format/formatZonedToParts.js +8 -5
- package/dist/zoned/get/getDstTransitions.d.ts +9 -10
- package/dist/zoned/get/getDstTransitions.js +12 -3
- package/dist/zoned/get/getTimeZoneOffset.d.ts +4 -1
- package/dist/zoned/get/getTimeZoneOffset.js +6 -3
- package/dist/zoned/get/getZonedNow.d.ts +13 -1
- package/dist/zoned/get/getZonedNow.js +12 -3
- package/dist/zoned/interval/intervalDifferenceZoned.d.ts +9 -0
- package/dist/zoned/interval/intervalDivideEquallyZoned.d.ts +22 -4
- package/dist/zoned/interval/intervalDivideEquallyZoned.js +6 -4
- package/dist/zoned/interval/intervalFromDurationZoned.d.ts +29 -10
- package/dist/zoned/interval/intervalFromDurationZoned.js +6 -13
- package/dist/zoned/interval/intervalIntersectionZoned.d.ts +9 -0
- package/dist/zoned/interval/intervalSplitAtZoned.d.ts +11 -0
- package/dist/zoned/interval/intervalSplitAtZoned.js +2 -0
- package/dist/zoned/interval/intervalUnionZoned.d.ts +9 -0
- package/dist/zoned/interval/intervalXorAllZoned.d.ts +9 -0
- package/dist/zoned/interval/intervalXorZoned.d.ts +9 -0
- package/dist/zoned/interval/mergeIntervalsZoned.d.ts +9 -0
- package/dist/zoned/interval/splitIntervalByUnitZoned.d.ts +27 -6
- package/dist/zoned/interval/splitIntervalByUnitZoned.js +11 -6
- package/dist/zoned/map/mapZonedDatesInRange.d.ts +9 -4
- package/dist/zoned/map/mapZonedDatesInRange.js +2 -4
- package/dist/zoned/parse/parseRfc2822.d.ts +1 -1
- package/dist/zoned/parse/parseRfc2822.js +1 -1
- package/dist/zoned/parse/parseUnitFromZoned.d.ts +9 -3
- package/dist/zoned/parse/parseUnitFromZoned.js +1 -3
- package/dist/zoned/parse/parseWeekFromZoned.d.ts +10 -3
- package/dist/zoned/parse/parseWeekFromZoned.js +2 -3
- package/dist/zoned/validate/hasDaylightSaving.d.ts +42 -11
- package/dist/zoned/validate/hasDaylightSaving.js +47 -31
- package/dist/zoned/validate/isValidZonedDateTime.d.ts +13 -0
- package/dist/zoned/validate/isValidZonedDateTime.js +14 -1
- package/dist/zoned/validate/isValidZonedRange.d.ts +15 -4
- package/dist/zoned/validate/isValidZonedRange.js +1 -4
- package/package.json +53 -5
- package/skills/gmt-arithmetic/SKILL.md +1 -1
- package/skills/gmt-basics/SKILL.md +10 -1
- package/skills/gmt-integration/SKILL.md +10 -5
- package/skills/gmt-timezone/SKILL.md +210 -14
- package/dist/internal/resolveReadingTimeZone.d.ts +0 -11
- package/dist/internal/resolveReadingTimeZone.js +0 -18
- package/dist/types/duration-unit.d.ts +0 -5
- /package/dist/types/{duration-unit.js → free-time-options.js} +0 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type { Interval } from "../../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* The events a container's charging clocks run between, named after the DCSA Track & Trace
|
|
4
|
+
* equipment events they correspond to (`equipmentEventTypeCode` with `emptyIndicatorCode`):
|
|
5
|
+
*
|
|
6
|
+
* - `discharged`: DISC, laden — the full container is discharged from the vessel (import).
|
|
7
|
+
* - `available`: no DCSA event — the container availability date some import tariffs start the
|
|
8
|
+
* clock at.
|
|
9
|
+
* - `gatedOut`: GTOT, laden — the full container leaves the terminal (import).
|
|
10
|
+
* - `emptyReturned`: GTIN, empty — the empty is returned to the terminal or depot (import).
|
|
11
|
+
* - `emptyReleased`: GTOT or PICK, empty — the empty is picked up for stuffing (export).
|
|
12
|
+
* - `gatedIn`: GTIN, laden — the full container is received at the terminal (export).
|
|
13
|
+
* - `loaded`: LOAD, laden — the full container is loaded on board (export).
|
|
14
|
+
*/
|
|
15
|
+
export type ClockEventType = "discharged" | "available" | "gatedOut" | "emptyReturned" | "emptyReleased" | "gatedIn" | "loaded";
|
|
16
|
+
/** A container event: what happened and the instant it happened. */
|
|
17
|
+
export interface ClockEvent {
|
|
18
|
+
/** What happened to the container, as one of the events a charging clock can start or end at. */
|
|
19
|
+
type: ClockEventType;
|
|
20
|
+
/** The instant it happened, as an ISO 8601 string: `Z`, an offset, or a bracketed zone. */
|
|
21
|
+
at: string;
|
|
22
|
+
}
|
|
23
|
+
/** Which charge is being clocked. `combined` is the merged demurrage-and-detention clock. */
|
|
24
|
+
export type ClockScope = "demurrage" | "detention" | "storage" | "combined";
|
|
25
|
+
/** Which leg of the container's cycle the clock is on. */
|
|
26
|
+
export type ClockDirection = "import" | "export";
|
|
27
|
+
/** Where an import demurrage, storage or combined clock starts, when the tariff says so. */
|
|
28
|
+
export type ClockStartEvent = "discharged" | "available";
|
|
29
|
+
/** The options `demurrageClock` reads. */
|
|
30
|
+
export interface ClockOptions {
|
|
31
|
+
/**
|
|
32
|
+
* The leg of the container's cycle, `"import"` or `"export"`; required, because the same scope
|
|
33
|
+
* runs between different events in each.
|
|
34
|
+
*/
|
|
35
|
+
direction: ClockDirection;
|
|
36
|
+
/**
|
|
37
|
+
* Where an import demurrage, storage or combined clock starts: `"discharged"`, the classic
|
|
38
|
+
* definition, or `"available"` for tariffs that start at the availability date. Not read for
|
|
39
|
+
* export or detention.
|
|
40
|
+
*
|
|
41
|
+
* @defaultValue `"discharged"`
|
|
42
|
+
*/
|
|
43
|
+
startEvent?: ClockStartEvent;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Pick the two events a charge's clock runs between.
|
|
47
|
+
*
|
|
48
|
+
* No regulation or industry standard fixes these events; the carriers' published tariffs agree
|
|
49
|
+
* on them (import: Maersk's terms, CMA CGM's general terms, Hapag-Lloyd, ACL; export: Maersk, CMA
|
|
50
|
+
* CGM, ACL), and DCSA's glossary draws the line they rest on: demurrage is charged while the
|
|
51
|
+
* container is inside the terminal or depot, detention while it is outside, and storage is the
|
|
52
|
+
* charge for the terminal's space, paid to the terminal or to the carrier on its behalf. Export
|
|
53
|
+
* storage (`gatedIn` → `loaded`) follows from that storage definition; no tariff read quotes it.
|
|
54
|
+
* The merged clock runs demurrage and detention as one period, a named tariff product at Maersk
|
|
55
|
+
* ("Combined"), CMA CGM ("merged") and MSC. `demurrageClock` selects the pair for the charge and
|
|
56
|
+
* direction asked for, so the wrong pair can never reach `chargeableDays`.
|
|
57
|
+
*
|
|
58
|
+
* | scope | import | export |
|
|
59
|
+
* | --- | --- | --- |
|
|
60
|
+
* | `demurrage`, `storage` | `startEvent` → `gatedOut` | `gatedIn` → `loaded` |
|
|
61
|
+
* | `detention` | `gatedOut` → `emptyReturned` | `emptyReleased` → `gatedIn` |
|
|
62
|
+
* | `combined` | `startEvent` → `emptyReturned` | `emptyReleased` → `loaded` |
|
|
63
|
+
*
|
|
64
|
+
* - **`direction` has no default.** The same scope name selects different events on the import and
|
|
65
|
+
* export legs, and guessing it from the events present would be a silent guess.
|
|
66
|
+
* - **`startEvent` is import only.** It is not read for detention or export, so one options
|
|
67
|
+
* object can serve every scope on a leg. A tariff that starts at
|
|
68
|
+
* customs release (Hapag-Lloyd Japan) or ends export demurrage at the cut-off or the scheduled
|
|
69
|
+
* sailing passes that instant as the event's `at`; GMT does not invent an event for one tariff.
|
|
70
|
+
* - Events may be in any order, and every one must be `{ type, at }` with a known type and a
|
|
71
|
+
* valid instant, used or not, with no holes in the array: a list with a bad entry is a bad list.
|
|
72
|
+
* - The result is an `Interval`, half-open `[start, end)`, in the caller's own strings, and feeds
|
|
73
|
+
* `chargeableDays(start, end, …)` directly.
|
|
74
|
+
* - Some tariffs differ in words, not events: MSC USA calls the in-terminal container charge
|
|
75
|
+
* "detention" and the out-of-terminal one "per diem". GMT's scope names follow the global usage.
|
|
76
|
+
* - Returns `null` when `events` is not an array or holds an invalid event or a hole, `scope`,
|
|
77
|
+
* `direction` or `startEvent` is unknown, `options` is not an object, a required event is
|
|
78
|
+
* missing or occurs more than once (a container discharged twice is a data error, not a choice),
|
|
79
|
+
* or the end event precedes the start event.
|
|
80
|
+
*
|
|
81
|
+
* @param events the container's events, `{ type, at }`, `type` one of discharged, available, gatedOut, emptyReturned, emptyReleased, gatedIn, loaded
|
|
82
|
+
* @param scope "demurrage" | "detention" | "storage" | "combined"
|
|
83
|
+
* @param options Which leg of the cycle the clock is on, and where an import clock starts
|
|
84
|
+
* @returns { start, end } of the requested clock, or null on invalid input
|
|
85
|
+
*
|
|
86
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-14T19:00:00Z" }, { type: "available", at: "2024-06-15T12:00:00Z" }, { type: "gatedOut", at: "2024-06-20T14:30:00Z" }, { type: "emptyReturned", at: "2024-06-27T09:00:00Z" }], "demurrage", { direction: "import" }) / { start: "2024-06-14T19:00:00Z", end: "2024-06-20T14:30:00Z" }
|
|
87
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-14T19:00:00Z" }, { type: "available", at: "2024-06-15T12:00:00Z" }, { type: "gatedOut", at: "2024-06-20T14:30:00Z" }, { type: "emptyReturned", at: "2024-06-27T09:00:00Z" }], "detention", { direction: "import" }) / { start: "2024-06-20T14:30:00Z", end: "2024-06-27T09:00:00Z" } (gate-out to empty return, not discharge)
|
|
88
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-14T19:00:00Z" }, { type: "available", at: "2024-06-15T12:00:00Z" }, { type: "gatedOut", at: "2024-06-20T14:30:00Z" }, { type: "emptyReturned", at: "2024-06-27T09:00:00Z" }], "combined", { direction: "import" }) / { start: "2024-06-14T19:00:00Z", end: "2024-06-27T09:00:00Z" } (merged: discharge to empty return)
|
|
89
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-14T19:00:00Z" }, { type: "available", at: "2024-06-15T12:00:00Z" }, { type: "gatedOut", at: "2024-06-20T14:30:00Z" }], "demurrage", { direction: "import", startEvent: "available" }) // { start: "2024-06-15T12:00:00Z", end: "2024-06-20T14:30:00Z" }
|
|
90
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-14T19:00:00Z" }, { type: "gatedOut", at: "2024-06-20T14:30:00Z" }], "storage", { direction: "import" }) / { start: "2024-06-14T19:00:00Z", end: "2024-06-20T14:30:00Z" }
|
|
91
|
+
* @example demurrageClock([{ type: "emptyReleased", at: "2024-07-01T08:00:00Z" }, { type: "gatedIn", at: "2024-07-05T16:00:00Z" }, { type: "loaded", at: "2024-07-09T03:00:00Z" }], "demurrage", { direction: "export" }) // { start: "2024-07-05T16:00:00Z", end: "2024-07-09T03:00:00Z" } (gate-in full to loaded on board)
|
|
92
|
+
* @example demurrageClock([{ type: "emptyReleased", at: "2024-07-01T08:00:00Z" }, { type: "gatedIn", at: "2024-07-05T16:00:00Z" }, { type: "loaded", at: "2024-07-09T03:00:00Z" }], "detention", { direction: "export" }) // { start: "2024-07-01T08:00:00Z", end: "2024-07-05T16:00:00Z" } (empty picked up to gate-in full)
|
|
93
|
+
* @example demurrageClock([{ type: "emptyReleased", at: "2024-07-01T08:00:00Z" }, { type: "gatedIn", at: "2024-07-05T16:00:00Z" }, { type: "loaded", at: "2024-07-09T03:00:00Z" }], "combined", { direction: "export" }) // { start: "2024-07-01T08:00:00Z", end: "2024-07-09T03:00:00Z" }
|
|
94
|
+
* @example demurrageClock([{ type: "gatedOut", at: "2024-06-20T10:30:00-04:00[America/New_York]" }, { type: "emptyReturned", at: "2024-06-27T09:00:00Z" }], "detention", { direction: "import", startEvent: "available" }) // { start: "2024-06-20T10:30:00-04:00[America/New_York]", end: "2024-06-27T09:00:00Z" } (startEvent is not read for detention; strings are echoed as given)
|
|
95
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-14T19:00:00Z" }, { type: "gatedOut", at: "2024-06-20T14:30:00Z" }], "demurrage") // null (direction has no default)
|
|
96
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-14T19:00:00Z" }, { type: "gatedOut", at: "2024-06-20T14:30:00Z" }], "demurrage", { direction: "import", startEvent: "available" }) // null (no availability event)
|
|
97
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-14T19:00:00Z" }], "demurrage", { direction: "import" }) // null (still in the terminal: no gate-out)
|
|
98
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-14T19:00:00Z" }, { type: "discharged", at: "2024-06-15T19:00:00Z" }, { type: "gatedOut", at: "2024-06-20T14:30:00Z" }], "demurrage", { direction: "import" }) // null (discharged twice)
|
|
99
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-21T19:00:00Z" }, { type: "gatedOut", at: "2024-06-20T14:30:00Z" }], "demurrage", { direction: "import" }) // null (gate-out before discharge)
|
|
100
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-14T19:00:00Z" }, { type: "gatedOut", at: "2024-06-20T14:30:00Z" }], "laytime", { direction: "import" }) // null (not a clock this function selects)
|
|
101
|
+
*/
|
|
102
|
+
export declare function demurrageClock(events: ClockEvent[], scope: ClockScope, options: ClockOptions): Interval | null;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
2
|
+
import { instantFrom, isObject } from "../../internal/index.js";
|
|
3
|
+
import { isValidInstant } from "../../precision/validate/isValidInstant.js";
|
|
4
|
+
import { optionOrDefault } from "../../internal/optionOrDefault.js";
|
|
5
|
+
const CLOCK_EVENT_TYPES = [
|
|
6
|
+
"discharged",
|
|
7
|
+
"available",
|
|
8
|
+
"gatedOut",
|
|
9
|
+
"emptyReturned",
|
|
10
|
+
"emptyReleased",
|
|
11
|
+
"gatedIn",
|
|
12
|
+
"loaded",
|
|
13
|
+
];
|
|
14
|
+
const CLOCK_SCOPES = [
|
|
15
|
+
"demurrage",
|
|
16
|
+
"detention",
|
|
17
|
+
"storage",
|
|
18
|
+
"combined",
|
|
19
|
+
];
|
|
20
|
+
const CLOCK_START_EVENTS = [
|
|
21
|
+
"discharged",
|
|
22
|
+
"available",
|
|
23
|
+
];
|
|
24
|
+
/** The export clocks: fixed pairs, no start-event choice. */
|
|
25
|
+
const EXPORT_CLOCKS = {
|
|
26
|
+
demurrage: ["gatedIn", "loaded"],
|
|
27
|
+
storage: ["gatedIn", "loaded"],
|
|
28
|
+
detention: ["emptyReleased", "gatedIn"],
|
|
29
|
+
combined: ["emptyReleased", "loaded"],
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Pick the two events a charge's clock runs between.
|
|
33
|
+
*
|
|
34
|
+
* No regulation or industry standard fixes these events; the carriers' published tariffs agree
|
|
35
|
+
* on them (import: Maersk's terms, CMA CGM's general terms, Hapag-Lloyd, ACL; export: Maersk, CMA
|
|
36
|
+
* CGM, ACL), and DCSA's glossary draws the line they rest on: demurrage is charged while the
|
|
37
|
+
* container is inside the terminal or depot, detention while it is outside, and storage is the
|
|
38
|
+
* charge for the terminal's space, paid to the terminal or to the carrier on its behalf. Export
|
|
39
|
+
* storage (`gatedIn` → `loaded`) follows from that storage definition; no tariff read quotes it.
|
|
40
|
+
* The merged clock runs demurrage and detention as one period, a named tariff product at Maersk
|
|
41
|
+
* ("Combined"), CMA CGM ("merged") and MSC. `demurrageClock` selects the pair for the charge and
|
|
42
|
+
* direction asked for, so the wrong pair can never reach `chargeableDays`.
|
|
43
|
+
*
|
|
44
|
+
* | scope | import | export |
|
|
45
|
+
* | --- | --- | --- |
|
|
46
|
+
* | `demurrage`, `storage` | `startEvent` → `gatedOut` | `gatedIn` → `loaded` |
|
|
47
|
+
* | `detention` | `gatedOut` → `emptyReturned` | `emptyReleased` → `gatedIn` |
|
|
48
|
+
* | `combined` | `startEvent` → `emptyReturned` | `emptyReleased` → `loaded` |
|
|
49
|
+
*
|
|
50
|
+
* - **`direction` has no default.** The same scope name selects different events on the import and
|
|
51
|
+
* export legs, and guessing it from the events present would be a silent guess.
|
|
52
|
+
* - **`startEvent` is import only.** It is not read for detention or export, so one options
|
|
53
|
+
* object can serve every scope on a leg. A tariff that starts at
|
|
54
|
+
* customs release (Hapag-Lloyd Japan) or ends export demurrage at the cut-off or the scheduled
|
|
55
|
+
* sailing passes that instant as the event's `at`; GMT does not invent an event for one tariff.
|
|
56
|
+
* - Events may be in any order, and every one must be `{ type, at }` with a known type and a
|
|
57
|
+
* valid instant, used or not, with no holes in the array: a list with a bad entry is a bad list.
|
|
58
|
+
* - The result is an `Interval`, half-open `[start, end)`, in the caller's own strings, and feeds
|
|
59
|
+
* `chargeableDays(start, end, …)` directly.
|
|
60
|
+
* - Some tariffs differ in words, not events: MSC USA calls the in-terminal container charge
|
|
61
|
+
* "detention" and the out-of-terminal one "per diem". GMT's scope names follow the global usage.
|
|
62
|
+
* - Returns `null` when `events` is not an array or holds an invalid event or a hole, `scope`,
|
|
63
|
+
* `direction` or `startEvent` is unknown, `options` is not an object, a required event is
|
|
64
|
+
* missing or occurs more than once (a container discharged twice is a data error, not a choice),
|
|
65
|
+
* or the end event precedes the start event.
|
|
66
|
+
*
|
|
67
|
+
* @param events the container's events, `{ type, at }`, `type` one of discharged, available, gatedOut, emptyReturned, emptyReleased, gatedIn, loaded
|
|
68
|
+
* @param scope "demurrage" | "detention" | "storage" | "combined"
|
|
69
|
+
* @param options Which leg of the cycle the clock is on, and where an import clock starts
|
|
70
|
+
* @returns { start, end } of the requested clock, or null on invalid input
|
|
71
|
+
*
|
|
72
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-14T19:00:00Z" }, { type: "available", at: "2024-06-15T12:00:00Z" }, { type: "gatedOut", at: "2024-06-20T14:30:00Z" }, { type: "emptyReturned", at: "2024-06-27T09:00:00Z" }], "demurrage", { direction: "import" }) / { start: "2024-06-14T19:00:00Z", end: "2024-06-20T14:30:00Z" }
|
|
73
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-14T19:00:00Z" }, { type: "available", at: "2024-06-15T12:00:00Z" }, { type: "gatedOut", at: "2024-06-20T14:30:00Z" }, { type: "emptyReturned", at: "2024-06-27T09:00:00Z" }], "detention", { direction: "import" }) / { start: "2024-06-20T14:30:00Z", end: "2024-06-27T09:00:00Z" } (gate-out to empty return, not discharge)
|
|
74
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-14T19:00:00Z" }, { type: "available", at: "2024-06-15T12:00:00Z" }, { type: "gatedOut", at: "2024-06-20T14:30:00Z" }, { type: "emptyReturned", at: "2024-06-27T09:00:00Z" }], "combined", { direction: "import" }) / { start: "2024-06-14T19:00:00Z", end: "2024-06-27T09:00:00Z" } (merged: discharge to empty return)
|
|
75
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-14T19:00:00Z" }, { type: "available", at: "2024-06-15T12:00:00Z" }, { type: "gatedOut", at: "2024-06-20T14:30:00Z" }], "demurrage", { direction: "import", startEvent: "available" }) // { start: "2024-06-15T12:00:00Z", end: "2024-06-20T14:30:00Z" }
|
|
76
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-14T19:00:00Z" }, { type: "gatedOut", at: "2024-06-20T14:30:00Z" }], "storage", { direction: "import" }) / { start: "2024-06-14T19:00:00Z", end: "2024-06-20T14:30:00Z" }
|
|
77
|
+
* @example demurrageClock([{ type: "emptyReleased", at: "2024-07-01T08:00:00Z" }, { type: "gatedIn", at: "2024-07-05T16:00:00Z" }, { type: "loaded", at: "2024-07-09T03:00:00Z" }], "demurrage", { direction: "export" }) // { start: "2024-07-05T16:00:00Z", end: "2024-07-09T03:00:00Z" } (gate-in full to loaded on board)
|
|
78
|
+
* @example demurrageClock([{ type: "emptyReleased", at: "2024-07-01T08:00:00Z" }, { type: "gatedIn", at: "2024-07-05T16:00:00Z" }, { type: "loaded", at: "2024-07-09T03:00:00Z" }], "detention", { direction: "export" }) // { start: "2024-07-01T08:00:00Z", end: "2024-07-05T16:00:00Z" } (empty picked up to gate-in full)
|
|
79
|
+
* @example demurrageClock([{ type: "emptyReleased", at: "2024-07-01T08:00:00Z" }, { type: "gatedIn", at: "2024-07-05T16:00:00Z" }, { type: "loaded", at: "2024-07-09T03:00:00Z" }], "combined", { direction: "export" }) // { start: "2024-07-01T08:00:00Z", end: "2024-07-09T03:00:00Z" }
|
|
80
|
+
* @example demurrageClock([{ type: "gatedOut", at: "2024-06-20T10:30:00-04:00[America/New_York]" }, { type: "emptyReturned", at: "2024-06-27T09:00:00Z" }], "detention", { direction: "import", startEvent: "available" }) // { start: "2024-06-20T10:30:00-04:00[America/New_York]", end: "2024-06-27T09:00:00Z" } (startEvent is not read for detention; strings are echoed as given)
|
|
81
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-14T19:00:00Z" }, { type: "gatedOut", at: "2024-06-20T14:30:00Z" }], "demurrage") // null (direction has no default)
|
|
82
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-14T19:00:00Z" }, { type: "gatedOut", at: "2024-06-20T14:30:00Z" }], "demurrage", { direction: "import", startEvent: "available" }) // null (no availability event)
|
|
83
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-14T19:00:00Z" }], "demurrage", { direction: "import" }) // null (still in the terminal: no gate-out)
|
|
84
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-14T19:00:00Z" }, { type: "discharged", at: "2024-06-15T19:00:00Z" }, { type: "gatedOut", at: "2024-06-20T14:30:00Z" }], "demurrage", { direction: "import" }) // null (discharged twice)
|
|
85
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-21T19:00:00Z" }, { type: "gatedOut", at: "2024-06-20T14:30:00Z" }], "demurrage", { direction: "import" }) // null (gate-out before discharge)
|
|
86
|
+
* @example demurrageClock([{ type: "discharged", at: "2024-06-14T19:00:00Z" }, { type: "gatedOut", at: "2024-06-20T14:30:00Z" }], "laytime", { direction: "import" }) // null (not a clock this function selects)
|
|
87
|
+
*/
|
|
88
|
+
export function demurrageClock(events, scope, options) {
|
|
89
|
+
try {
|
|
90
|
+
return selectClock(events, scope, options);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// Never throws (Core Rule 3): a hostile
|
|
94
|
+
// argument is invalid input, not an exception.
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/** `demurrageClock` without the guard; every read of its arguments happens here. */
|
|
99
|
+
function selectClock(events, scope, options) {
|
|
100
|
+
if (!Array.isArray(events) ||
|
|
101
|
+
!CLOCK_SCOPES.includes(scope) ||
|
|
102
|
+
!isObject(options)) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
const { direction } = options;
|
|
106
|
+
if (direction !== "import" && direction !== "export") {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
// An explicit `undefined` is an omission (TC39 GetOption); `null` is a value, and not a valid one.
|
|
110
|
+
const startEvent = optionOrDefault(options.startEvent, "discharged");
|
|
111
|
+
if (!CLOCK_START_EVENTS.includes(startEvent)) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
// `Array.from` turns a hole into `undefined`, which the check rejects; `every` would skip it.
|
|
115
|
+
const list = Array.from(events);
|
|
116
|
+
const wellFormed = list.every((event) => isObject(event) &&
|
|
117
|
+
CLOCK_EVENT_TYPES.includes(event.type) &&
|
|
118
|
+
typeof event.at === "string" &&
|
|
119
|
+
isValidInstant(event.at));
|
|
120
|
+
if (!wellFormed) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
const [startType, endType] = direction === "export"
|
|
124
|
+
? EXPORT_CLOCKS[scope]
|
|
125
|
+
: scope === "detention"
|
|
126
|
+
? ["gatedOut", "emptyReturned"]
|
|
127
|
+
: [startEvent, scope === "combined" ? "emptyReturned" : "gatedOut"];
|
|
128
|
+
const only = (type) => {
|
|
129
|
+
const matches = list.filter((event) => event.type === type);
|
|
130
|
+
return matches.length === 1 ? matches[0].at : null;
|
|
131
|
+
};
|
|
132
|
+
const start = only(startType);
|
|
133
|
+
const end = only(endType);
|
|
134
|
+
if (start === null || end === null) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
return Temporal.Instant.compare(instantFrom(start), instantFrom(end)) > 0
|
|
138
|
+
? null
|
|
139
|
+
: { start, end };
|
|
140
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { FreeTimeOptions } from "../../types/index.js";
|
|
2
|
+
/** What `freeTimeExpiry` returns: the free-time window as local dates, and the instant it ends. */
|
|
3
|
+
export interface FreeTime {
|
|
4
|
+
/** The first free day, as a local date in the counting zone. */
|
|
5
|
+
freeTimeStart: string;
|
|
6
|
+
/** The last free day, as a local date in the counting zone. */
|
|
7
|
+
lastFreeDay: string;
|
|
8
|
+
/** The instant free time ends: the start of the local day after `lastFreeDay`, as a UTC instant. */
|
|
9
|
+
expiresAt: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Lay out a container's free time from the instant its clock started, and say when it ends.
|
|
13
|
+
*
|
|
14
|
+
* Free time is the money calculation in container logistics, and none of its terms is a fact
|
|
15
|
+
* about the port: the number of free days, whether the day of discharge is free day one, and
|
|
16
|
+
* whether weekends count are all set by the carrier's tariff or the service contract. So every
|
|
17
|
+
* term is a parameter. No regulation or industry standard fixes how free time is counted (DCSA types only its unit: calendar days, working days, hours or day of discharge; GMT counts
|
|
18
|
+
* days); the result is the window every tariff states, and what an invoice can print about it:
|
|
19
|
+
* the free time allowed and the dates it starts and ends.
|
|
20
|
+
*
|
|
21
|
+
* - **Days are the terminal's local days.** `clockStart` is an instant (`Z`, an offset, or a
|
|
22
|
+
* bracketed zone, of which only the instant is read, a minute-rounded offset as the zone's
|
|
23
|
+
* real one, as `isValidInstant` describes); its local date in `options.timeZone` is the
|
|
24
|
+
* event day. A container discharged at 23:00 has used a free day by 00:01 under
|
|
25
|
+
* `firstDay: "eventDay"`. Day boundaries are the zone's real ones, as `floorToZone` and
|
|
26
|
+
* `dwellTime` find them: a 23- or 25-hour day is one day, a date the zone deleted is never a
|
|
27
|
+
* free day, and a fall-back that re-enters an earlier date never moves the count backwards.
|
|
28
|
+
* - **`firstDay` has no default.** `"eventDay"` makes the event day free day one; `"nextDay"`
|
|
29
|
+
* starts free time on the following counted day. The two differ by exactly one day of charges,
|
|
30
|
+
* and a silent default here is a wrong invoice, so omitting it returns `null`.
|
|
31
|
+
* - **`basis` decides which days count.** `"calendar"` counts every local day, so a weekend
|
|
32
|
+
* burns two free days while the terminal is shut. `"working"` counts only the working days of
|
|
33
|
+
* `options.calendar` (its weekend and holidays; `calendar.timeZone` is not read), and is
|
|
34
|
+
* required to have one: a working-day count without a calendar is a guess and returns `null`.
|
|
35
|
+
* Under `"working"` a Saturday discharge starts free time on Monday under either `firstDay`.
|
|
36
|
+
* A tariff counting "calendar days excluding bank holidays" (Hapag-Lloyd Japan, MSC Vietnam) is
|
|
37
|
+
* `"working"` with an empty `weekend`. How days after expiry are charged is a separate term;
|
|
38
|
+
* see `chargeableDays`'s `chargeBasis`.
|
|
39
|
+
* - **`expiresAt` is half-open.** It is the first instant of the local day after `lastFreeDay`,
|
|
40
|
+
* as a UTC instant. A gate-out at exactly `expiresAt` is not a chargeable day; see
|
|
41
|
+
* `chargeableDays`. Under `"working"` it can fall on a weekend, which is then simply not
|
|
42
|
+
* chargeable.
|
|
43
|
+
* - `freeDays` is a whole number of at least `1`: with no free days there is no last free day
|
|
44
|
+
* to name, and `chargeableDays` accepts `0` for that tariff.
|
|
45
|
+
* - Returns `null` when `clockStart` is not an instant, `freeDays` is not a whole number of at
|
|
46
|
+
* least `1`, `options` is not an object, `basis` or `firstDay` is missing or unknown,
|
|
47
|
+
* `timeZone` is invalid, `basis` is `"working"` without a valid `BusinessCalendar`, or the walk
|
|
48
|
+
* would pass 10,000 local days.
|
|
49
|
+
*
|
|
50
|
+
* @param clockStart ISO 8601 instant string of the event that starts the clock (discharge, availability or gate-out)
|
|
51
|
+
* @param freeDays whole number of free days the tariff allows, at least 1
|
|
52
|
+
* @param options The tariff's counting terms: which days count, in which zone, and where day one starts
|
|
53
|
+
* @returns the free-time start and last free day as local dates, and the expiry instant, or null on invalid input
|
|
54
|
+
*
|
|
55
|
+
* @example freeTimeExpiry("2024-06-14T19:00:00Z", 3, { basis: "calendar", timeZone: "America/New_York", firstDay: "eventDay" }) // { freeTimeStart: "2024-06-14", lastFreeDay: "2024-06-16", expiresAt: "2024-06-17T04:00:00Z" } (a Friday discharge: the weekend is consumed)
|
|
56
|
+
* @example freeTimeExpiry("2024-06-14T19:00:00Z", 3, { basis: "calendar", timeZone: "America/New_York", firstDay: "nextDay" }) // { freeTimeStart: "2024-06-15", lastFreeDay: "2024-06-17", expiresAt: "2024-06-18T04:00:00Z" } (the same tariff read the other way: one more day)
|
|
57
|
+
* @example freeTimeExpiry("2024-06-14T19:00:00Z", 3, { basis: "working", timeZone: "America/New_York", firstDay: "eventDay", calendar: { weekend: [6, 7], holidays: [], timeZone: "America/New_York" } }) // { freeTimeStart: "2024-06-14", lastFreeDay: "2024-06-18", expiresAt: "2024-06-19T04:00:00Z" } (Friday, Monday, Tuesday: the weekend does not count)
|
|
58
|
+
* @example freeTimeExpiry("2024-06-14T19:00:00Z", 3, { basis: "working", timeZone: "America/New_York", firstDay: "eventDay", calendar: { weekend: [6, 7], holidays: ["2024-06-17"], timeZone: "America/New_York" } }) // { freeTimeStart: "2024-06-14", lastFreeDay: "2024-06-19", expiresAt: "2024-06-20T04:00:00Z" } (a terminal holiday on the Monday moves expiry a day)
|
|
59
|
+
* @example freeTimeExpiry("2024-06-15T14:00:00Z", 2, { basis: "working", timeZone: "America/New_York", firstDay: "eventDay", calendar: { weekend: [6, 7], holidays: [], timeZone: "America/New_York" } }) // { freeTimeStart: "2024-06-17", lastFreeDay: "2024-06-18", expiresAt: "2024-06-19T04:00:00Z" } (a Saturday discharge: free time starts Monday)
|
|
60
|
+
* @example freeTimeExpiry("2024-06-15T03:00:00Z", 1, { basis: "calendar", timeZone: "America/New_York", firstDay: "eventDay" }) // { freeTimeStart: "2024-06-14", lastFreeDay: "2024-06-14", expiresAt: "2024-06-15T04:00:00Z" } (23:00 local on the 14th: the free day is over an hour later)
|
|
61
|
+
* @example freeTimeExpiry("2024-09-07T15:00:00Z", 1, { basis: "calendar", timeZone: "America/Santiago", firstDay: "eventDay" }) // { freeTimeStart: "2024-09-07", lastFreeDay: "2024-09-07", expiresAt: "2024-09-08T04:00:00Z" } (Santiago skipped midnight on the 8th, so the day starts at 01:00)
|
|
62
|
+
* @example freeTimeExpiry("2024-06-14T19:00:00Z", 3, { basis: "calendar", timeZone: "America/New_York" }) // null (firstDay has no default)
|
|
63
|
+
* @example freeTimeExpiry("2024-06-14T19:00:00Z", 3, { basis: "working", timeZone: "America/New_York", firstDay: "eventDay" }) // null (a working-day count needs the terminal's calendar)
|
|
64
|
+
* @example freeTimeExpiry("2024-06-14T19:00:00Z", 0, { basis: "calendar", timeZone: "America/New_York", firstDay: "eventDay" }) // null (no free days means no last free day)
|
|
65
|
+
* @example freeTimeExpiry("2024-06-14T19:00:00", 3, { basis: "calendar", timeZone: "America/New_York", firstDay: "eventDay" }) // null (no offset: not an instant)
|
|
66
|
+
*/
|
|
67
|
+
export declare function freeTimeExpiry(clockStart: string, freeDays: number, options: FreeTimeOptions): FreeTime | null;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { instantFrom, parseFreeDays, parseFreeTimeTerms, walkFreeTime, } from "../../internal/index.js";
|
|
2
|
+
import { isValidInstant } from "../../precision/validate/isValidInstant.js";
|
|
3
|
+
/**
|
|
4
|
+
* Lay out a container's free time from the instant its clock started, and say when it ends.
|
|
5
|
+
*
|
|
6
|
+
* Free time is the money calculation in container logistics, and none of its terms is a fact
|
|
7
|
+
* about the port: the number of free days, whether the day of discharge is free day one, and
|
|
8
|
+
* whether weekends count are all set by the carrier's tariff or the service contract. So every
|
|
9
|
+
* term is a parameter. No regulation or industry standard fixes how free time is counted (DCSA types only its unit: calendar days, working days, hours or day of discharge; GMT counts
|
|
10
|
+
* days); the result is the window every tariff states, and what an invoice can print about it:
|
|
11
|
+
* the free time allowed and the dates it starts and ends.
|
|
12
|
+
*
|
|
13
|
+
* - **Days are the terminal's local days.** `clockStart` is an instant (`Z`, an offset, or a
|
|
14
|
+
* bracketed zone, of which only the instant is read, a minute-rounded offset as the zone's
|
|
15
|
+
* real one, as `isValidInstant` describes); its local date in `options.timeZone` is the
|
|
16
|
+
* event day. A container discharged at 23:00 has used a free day by 00:01 under
|
|
17
|
+
* `firstDay: "eventDay"`. Day boundaries are the zone's real ones, as `floorToZone` and
|
|
18
|
+
* `dwellTime` find them: a 23- or 25-hour day is one day, a date the zone deleted is never a
|
|
19
|
+
* free day, and a fall-back that re-enters an earlier date never moves the count backwards.
|
|
20
|
+
* - **`firstDay` has no default.** `"eventDay"` makes the event day free day one; `"nextDay"`
|
|
21
|
+
* starts free time on the following counted day. The two differ by exactly one day of charges,
|
|
22
|
+
* and a silent default here is a wrong invoice, so omitting it returns `null`.
|
|
23
|
+
* - **`basis` decides which days count.** `"calendar"` counts every local day, so a weekend
|
|
24
|
+
* burns two free days while the terminal is shut. `"working"` counts only the working days of
|
|
25
|
+
* `options.calendar` (its weekend and holidays; `calendar.timeZone` is not read), and is
|
|
26
|
+
* required to have one: a working-day count without a calendar is a guess and returns `null`.
|
|
27
|
+
* Under `"working"` a Saturday discharge starts free time on Monday under either `firstDay`.
|
|
28
|
+
* A tariff counting "calendar days excluding bank holidays" (Hapag-Lloyd Japan, MSC Vietnam) is
|
|
29
|
+
* `"working"` with an empty `weekend`. How days after expiry are charged is a separate term;
|
|
30
|
+
* see `chargeableDays`'s `chargeBasis`.
|
|
31
|
+
* - **`expiresAt` is half-open.** It is the first instant of the local day after `lastFreeDay`,
|
|
32
|
+
* as a UTC instant. A gate-out at exactly `expiresAt` is not a chargeable day; see
|
|
33
|
+
* `chargeableDays`. Under `"working"` it can fall on a weekend, which is then simply not
|
|
34
|
+
* chargeable.
|
|
35
|
+
* - `freeDays` is a whole number of at least `1`: with no free days there is no last free day
|
|
36
|
+
* to name, and `chargeableDays` accepts `0` for that tariff.
|
|
37
|
+
* - Returns `null` when `clockStart` is not an instant, `freeDays` is not a whole number of at
|
|
38
|
+
* least `1`, `options` is not an object, `basis` or `firstDay` is missing or unknown,
|
|
39
|
+
* `timeZone` is invalid, `basis` is `"working"` without a valid `BusinessCalendar`, or the walk
|
|
40
|
+
* would pass 10,000 local days.
|
|
41
|
+
*
|
|
42
|
+
* @param clockStart ISO 8601 instant string of the event that starts the clock (discharge, availability or gate-out)
|
|
43
|
+
* @param freeDays whole number of free days the tariff allows, at least 1
|
|
44
|
+
* @param options The tariff's counting terms: which days count, in which zone, and where day one starts
|
|
45
|
+
* @returns the free-time start and last free day as local dates, and the expiry instant, or null on invalid input
|
|
46
|
+
*
|
|
47
|
+
* @example freeTimeExpiry("2024-06-14T19:00:00Z", 3, { basis: "calendar", timeZone: "America/New_York", firstDay: "eventDay" }) // { freeTimeStart: "2024-06-14", lastFreeDay: "2024-06-16", expiresAt: "2024-06-17T04:00:00Z" } (a Friday discharge: the weekend is consumed)
|
|
48
|
+
* @example freeTimeExpiry("2024-06-14T19:00:00Z", 3, { basis: "calendar", timeZone: "America/New_York", firstDay: "nextDay" }) // { freeTimeStart: "2024-06-15", lastFreeDay: "2024-06-17", expiresAt: "2024-06-18T04:00:00Z" } (the same tariff read the other way: one more day)
|
|
49
|
+
* @example freeTimeExpiry("2024-06-14T19:00:00Z", 3, { basis: "working", timeZone: "America/New_York", firstDay: "eventDay", calendar: { weekend: [6, 7], holidays: [], timeZone: "America/New_York" } }) // { freeTimeStart: "2024-06-14", lastFreeDay: "2024-06-18", expiresAt: "2024-06-19T04:00:00Z" } (Friday, Monday, Tuesday: the weekend does not count)
|
|
50
|
+
* @example freeTimeExpiry("2024-06-14T19:00:00Z", 3, { basis: "working", timeZone: "America/New_York", firstDay: "eventDay", calendar: { weekend: [6, 7], holidays: ["2024-06-17"], timeZone: "America/New_York" } }) // { freeTimeStart: "2024-06-14", lastFreeDay: "2024-06-19", expiresAt: "2024-06-20T04:00:00Z" } (a terminal holiday on the Monday moves expiry a day)
|
|
51
|
+
* @example freeTimeExpiry("2024-06-15T14:00:00Z", 2, { basis: "working", timeZone: "America/New_York", firstDay: "eventDay", calendar: { weekend: [6, 7], holidays: [], timeZone: "America/New_York" } }) // { freeTimeStart: "2024-06-17", lastFreeDay: "2024-06-18", expiresAt: "2024-06-19T04:00:00Z" } (a Saturday discharge: free time starts Monday)
|
|
52
|
+
* @example freeTimeExpiry("2024-06-15T03:00:00Z", 1, { basis: "calendar", timeZone: "America/New_York", firstDay: "eventDay" }) // { freeTimeStart: "2024-06-14", lastFreeDay: "2024-06-14", expiresAt: "2024-06-15T04:00:00Z" } (23:00 local on the 14th: the free day is over an hour later)
|
|
53
|
+
* @example freeTimeExpiry("2024-09-07T15:00:00Z", 1, { basis: "calendar", timeZone: "America/Santiago", firstDay: "eventDay" }) // { freeTimeStart: "2024-09-07", lastFreeDay: "2024-09-07", expiresAt: "2024-09-08T04:00:00Z" } (Santiago skipped midnight on the 8th, so the day starts at 01:00)
|
|
54
|
+
* @example freeTimeExpiry("2024-06-14T19:00:00Z", 3, { basis: "calendar", timeZone: "America/New_York" }) // null (firstDay has no default)
|
|
55
|
+
* @example freeTimeExpiry("2024-06-14T19:00:00Z", 3, { basis: "working", timeZone: "America/New_York", firstDay: "eventDay" }) // null (a working-day count needs the terminal's calendar)
|
|
56
|
+
* @example freeTimeExpiry("2024-06-14T19:00:00Z", 0, { basis: "calendar", timeZone: "America/New_York", firstDay: "eventDay" }) // null (no free days means no last free day)
|
|
57
|
+
* @example freeTimeExpiry("2024-06-14T19:00:00", 3, { basis: "calendar", timeZone: "America/New_York", firstDay: "eventDay" }) // null (no offset: not an instant)
|
|
58
|
+
*/
|
|
59
|
+
export function freeTimeExpiry(clockStart, freeDays, options) {
|
|
60
|
+
try {
|
|
61
|
+
const terms = parseFreeTimeTerms(options);
|
|
62
|
+
const allowed = parseFreeDays(freeDays, 1);
|
|
63
|
+
if (!isValidInstant(clockStart) || terms === null || allowed === null) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
const start = instantFrom(clockStart).toZonedDateTimeISO(terms.timeZone);
|
|
67
|
+
const ledger = walkFreeTime(start, allowed, terms);
|
|
68
|
+
if (ledger === null) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
freeTimeStart: ledger.free[0].date,
|
|
73
|
+
lastFreeDay: ledger.free[allowed - 1].date,
|
|
74
|
+
expiresAt: ledger.expiresAt.toInstant().toString(),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// Never throws (Core Rule 3): a hostile
|
|
79
|
+
// argument is invalid input, not an exception.
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -11,6 +11,11 @@ export type ResolvedBusinessCalendar = {
|
|
|
11
11
|
holidays: Set<string>;
|
|
12
12
|
};
|
|
13
13
|
export declare const DEFAULT_BUSINESS_CALENDAR: ResolvedBusinessCalendar;
|
|
14
|
+
/**
|
|
15
|
+
* Reduce a holiday list to its normalised ISO dates, or `null` when it is not an array of ISO
|
|
16
|
+
* PlainDate strings. Shared with `OperatingSchedule.holidays`, which takes the same list.
|
|
17
|
+
*/
|
|
18
|
+
export declare function parseHolidays(holidays: unknown): Set<string> | null;
|
|
14
19
|
/**
|
|
15
20
|
* Reduce a caller-supplied `BusinessCalendar` to its lookups, or `null` when it is not one.
|
|
16
21
|
*
|
|
@@ -29,7 +29,11 @@ function parseWeekend(weekend) {
|
|
|
29
29
|
// All seven weekdays closed leaves no business day, so every walk would run to its cap.
|
|
30
30
|
return days.size < ISO_WEEKDAYS ? days : null;
|
|
31
31
|
}
|
|
32
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Reduce a holiday list to its normalised ISO dates, or `null` when it is not an array of ISO
|
|
34
|
+
* PlainDate strings. Shared with `OperatingSchedule.holidays`, which takes the same list.
|
|
35
|
+
*/
|
|
36
|
+
export function parseHolidays(holidays) {
|
|
33
37
|
if (!Array.isArray(holidays)) {
|
|
34
38
|
return null;
|
|
35
39
|
}
|
|
@@ -8,10 +8,12 @@
|
|
|
8
8
|
* not by repeatedly correcting a single overflow.
|
|
9
9
|
* - Round path is **not** "round to nearest": it steps by `Math.sign(amount)` first, then snaps to
|
|
10
10
|
* the next multiple of `Math.abs(amount)` in the direction of that sign (ceiling for positive
|
|
11
|
-
* amounts, floor for negative). Multiples are relative to `0`, not `bounds.min`.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* (the next multiple of 15 above 22), not `15` (the nearest multiple).
|
|
11
|
+
* amounts, floor for negative). Multiples are relative to `0`, not `bounds.min`. GMT's own
|
|
12
|
+
* rule, not a standard's: a cycle always moves the way `amount` points, and the nearest
|
|
13
|
+
* multiple can lie the other way — e.g. minute `22` cycled by `+15` with `round: true` lands on
|
|
14
|
+
* `30` (the next multiple of 15 above 22), not `15` (the nearest multiple).
|
|
15
|
+
* - Comparison: `@internationalized/date`'s `CycleOptions.round` rounds a bounded field the same
|
|
16
|
+
* way.
|
|
15
17
|
*
|
|
16
18
|
* @param current the field's current numeric value
|
|
17
19
|
* @param amount signed amount to cycle by
|
|
@@ -8,10 +8,12 @@
|
|
|
8
8
|
* not by repeatedly correcting a single overflow.
|
|
9
9
|
* - Round path is **not** "round to nearest": it steps by `Math.sign(amount)` first, then snaps to
|
|
10
10
|
* the next multiple of `Math.abs(amount)` in the direction of that sign (ceiling for positive
|
|
11
|
-
* amounts, floor for negative). Multiples are relative to `0`, not `bounds.min`.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* (the next multiple of 15 above 22), not `15` (the nearest multiple).
|
|
11
|
+
* amounts, floor for negative). Multiples are relative to `0`, not `bounds.min`. GMT's own
|
|
12
|
+
* rule, not a standard's: a cycle always moves the way `amount` points, and the nearest
|
|
13
|
+
* multiple can lie the other way — e.g. minute `22` cycled by `+15` with `round: true` lands on
|
|
14
|
+
* `30` (the next multiple of 15 above 22), not `15` (the nearest multiple).
|
|
15
|
+
* - Comparison: `@internationalized/date`'s `CycleOptions.round` rounds a bounded field the same
|
|
16
|
+
* way.
|
|
15
17
|
*
|
|
16
18
|
* @param current the field's current numeric value
|
|
17
19
|
* @param amount signed amount to cycle by
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Temporal } from "@js-temporal/polyfill";
|
|
2
|
+
/**
|
|
3
|
+
* Whether an instant is in daylight saving time, read from the zone's offset changes alone.
|
|
4
|
+
*
|
|
5
|
+
* The rule: daylight time runs from a forward change of the clocks to the backward change that
|
|
6
|
+
* undoes it. A backward change undoes the most recent forward change of the same size that is not
|
|
7
|
+
* yet undone, and only if it comes less than 365 days after it. An instant is in daylight time when
|
|
8
|
+
* it is at or after such a forward change and before the backward change paired with it.
|
|
9
|
+
*
|
|
10
|
+
* A forward change that is never undone, or undone a year or more later, is a change of standard
|
|
11
|
+
* time (`Europe/Istanbul` 2016, `Europe/Moscow` 2011 to 2014), as is any backward change with no
|
|
12
|
+
* forward change to undo (`Asia/Almaty` 2024).
|
|
13
|
+
*
|
|
14
|
+
* This is GMT's own definition, not the tz database's daylight flag, which no JavaScript API
|
|
15
|
+
* exposes and offsets do not determine.
|
|
16
|
+
*
|
|
17
|
+
* Cost: one transition lookup forward, then one back, and more only outside the ordinary summer
|
|
18
|
+
* case. A paired change is less than 365 days away, so every lookup is given that limit and reads
|
|
19
|
+
* no further: with GMT's own search (temporalCompat D13) at most 74 offset samples and 51 reads to
|
|
20
|
+
* pin a change, for any zone and any instant.
|
|
21
|
+
*
|
|
22
|
+
* @param zoned the instant, in the zone to read
|
|
23
|
+
* @returns true in daylight time, false in standard time or when the walk exceeds its bound
|
|
24
|
+
*/
|
|
25
|
+
export declare function isInDaylightTime(zoned: Temporal.ZonedDateTime): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Whether a zone observes daylight saving time as of an instant: the instant is in daylight time,
|
|
28
|
+
* or a daylight period begins within the 365 days after it. Same rule as `isInDaylightTime`.
|
|
29
|
+
*
|
|
30
|
+
* @param zoned the instant to judge from, in the zone to read
|
|
31
|
+
* @returns true when the zone observes daylight time then, false otherwise or past the walk bound
|
|
32
|
+
*/
|
|
33
|
+
export declare function observesDaylightTime(zoned: Temporal.ZonedDateTime): boolean;
|