@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.
- package/README.md +462 -22
- 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/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 +3 -1
- package/dist/instant/convert/resolveLocal.d.ts +12 -7
- package/dist/instant/convert/resolveLocal.js +6 -10
- package/dist/instant/convert/toOffsetInstant.d.ts +22 -9
- package/dist/instant/convert/toOffsetInstant.js +10 -3
- package/dist/intermodal/calculate/billingTimeline.d.ts +31 -11
- package/dist/intermodal/calculate/billingTimeline.js +2 -2
- package/dist/intermodal/calculate/chargeableDays.d.ts +13 -11
- package/dist/intermodal/calculate/chargeableDays.js +4 -9
- package/dist/intermodal/calculate/demurrageClock.d.ts +16 -7
- package/dist/intermodal/calculate/demurrageClock.js +7 -7
- package/dist/intermodal/calculate/freeTimeExpiry.d.ts +5 -4
- package/dist/intermodal/calculate/freeTimeExpiry.js +6 -6
- 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/index.d.ts +9 -4
- package/dist/internal/index.js +9 -4
- 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/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/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/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 +16 -7
- package/dist/transport/calculate/dwellTime.js +12 -8
- package/dist/transport/calculate/estimateDrift.d.ts +65 -0
- package/dist/transport/calculate/estimateDrift.js +75 -0
- package/dist/transport/calculate/index.d.ts +8 -0
- package/dist/transport/calculate/index.js +8 -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 +21 -3
- package/dist/transport/calculate/transitTime.js +29 -46
- 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 +7 -0
- package/dist/transport/convert/etaAtZone.js +9 -4
- package/dist/transport/index.d.ts +1 -0
- package/dist/transport/index.js +1 -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 +21 -11
- package/dist/types/index.d.ts +2 -1
- package/dist/types/index.js +2 -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/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 +18 -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 +150 -21
- 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 → operating-schedule.js} +0 -0
|
@@ -68,7 +68,8 @@ function closedAtRangeLimit(slices, current, end, maxSlices) {
|
|
|
68
68
|
* - A step that goes backwards returns `null`.
|
|
69
69
|
* - More than `maxSlices` slices returns `null` as soon as the next one is due, so the work stays
|
|
70
70
|
* bounded by the limit (owner decision A2, CORE-8).
|
|
71
|
-
* - The last slice's end is
|
|
71
|
+
* - The last slice's end is `end` itself, whether the last step passes `end` (trimmed) or lands on
|
|
72
|
+
* it. Callers handle `start >= end` before calling.
|
|
72
73
|
* - A step that throws a RangeError (it lands past Temporal's last representable value, so after
|
|
73
74
|
* `end`) closes the split with a last slice ending at `end`.
|
|
74
75
|
*
|
|
@@ -111,7 +112,9 @@ export function tileByUnit(start, end, compare, unit, amount, maxSlices, add = (
|
|
|
111
112
|
return null;
|
|
112
113
|
}
|
|
113
114
|
stalled = 0;
|
|
114
|
-
|
|
115
|
+
// A step that lands on `end` closes with `end` itself, as a trimmed one does: the two compare
|
|
116
|
+
// equal but may be written differently (a zoned `end` in another zone than `start`).
|
|
117
|
+
slices.push([current, compare(next, end) >= 0 ? end : next]);
|
|
115
118
|
current = next;
|
|
116
119
|
}
|
|
117
120
|
return slices;
|
|
@@ -135,6 +138,35 @@ const LONGEST_UNIT_NANOSECONDS = {
|
|
|
135
138
|
months: 31 * NANOSECONDS_PER_DAY,
|
|
136
139
|
years: 385 * NANOSECONDS_PER_DAY,
|
|
137
140
|
};
|
|
141
|
+
/**
|
|
142
|
+
* The step a split takes when its boundaries are then floored to whole `floorUnit`s.
|
|
143
|
+
*
|
|
144
|
+
* - An exact step shorter than one `floorUnit` moves each boundary by less than one unit, so the
|
|
145
|
+
* floored boundaries are every whole unit from the start to the end, each one repeated once per
|
|
146
|
+
* step that falls inside it. Stepping by one `floorUnit` gives those boundaries once each: no
|
|
147
|
+
* empty piece, and no work spent on steps the result cannot show.
|
|
148
|
+
* - Any other step is returned unchanged: a step of one `floorUnit` or more never floors two
|
|
149
|
+
* boundaries to the same value, a calendar step is never shorter than a second, and a
|
|
150
|
+
* fractional `amount` is left for Temporal to reject.
|
|
151
|
+
* - The split's start must itself be a whole `floorUnit`, as a Unix epoch is.
|
|
152
|
+
*
|
|
153
|
+
* @param unit plural duration unit, as returned by `resolveDurationUnit`
|
|
154
|
+
* @param amount positive number of units per step
|
|
155
|
+
* @param floorUnit plural exact unit the boundaries are floored to
|
|
156
|
+
* @returns the `[unit, amount]` to step by
|
|
157
|
+
*
|
|
158
|
+
* @example stepNoFinerThan("milliseconds", 500, "seconds") // ["seconds", 1]
|
|
159
|
+
* @example stepNoFinerThan("milliseconds", 1500, "seconds") // ["milliseconds", 1500]
|
|
160
|
+
* @example stepNoFinerThan("days", 1, "seconds") // ["days", 1]
|
|
161
|
+
*/
|
|
162
|
+
export function stepNoFinerThan(unit, amount, floorUnit) {
|
|
163
|
+
const isFiner = isExactDurationUnit(unit) &&
|
|
164
|
+
isExactDurationUnit(floorUnit) &&
|
|
165
|
+
Number.isInteger(amount) &&
|
|
166
|
+
LONGEST_UNIT_NANOSECONDS[unit] * amount <
|
|
167
|
+
LONGEST_UNIT_NANOSECONDS[floorUnit];
|
|
168
|
+
return isFiner ? [floorUnit, 1] : [unit, amount];
|
|
169
|
+
}
|
|
138
170
|
/**
|
|
139
171
|
* A zoned boundary can sit this far from its wall-clock distance: a UTC offset lies strictly
|
|
140
172
|
* within ±24 hours (Temporal IsOffsetTimeZoneIdentifier / ECMA-262 time zone offset range), so
|
|
@@ -5,6 +5,7 @@ import { resolveDateTimeUnit } from "./resolveDateTimeUnit.js";
|
|
|
5
5
|
import { resolveWeekStartsOn } from "./resolveWeekStartsOn.js";
|
|
6
6
|
import { isValidDateTimeUnit } from "../plain/validate/index.js";
|
|
7
7
|
import { isValidZonedDateTime } from "../zoned/validate/index.js";
|
|
8
|
+
import { optionOrDefault } from "./optionOrDefault.js";
|
|
8
9
|
/**
|
|
9
10
|
* Internal shared implementation for `startOfZoned` / `endOfZoned`.
|
|
10
11
|
*
|
|
@@ -32,9 +33,7 @@ export function startOrEndOfZoned(value, unit, options, isEnd) {
|
|
|
32
33
|
// An end is next start − 1 ns, so it defaults to nanosecond precision: fewer digits would
|
|
33
34
|
// print an earlier instant than the end (Calendar & zone semantics §3).
|
|
34
35
|
const fractionalSecondDigits = isEnd
|
|
35
|
-
? options.fractionalSecondDigits
|
|
36
|
-
? 9
|
|
37
|
-
: options.fractionalSecondDigits
|
|
36
|
+
? optionOrDefault(options.fractionalSecondDigits, 9)
|
|
38
37
|
: defaultFractionalDigits(resolvedUnit, options.fractionalSecondDigits);
|
|
39
38
|
try {
|
|
40
39
|
const source = zonedDateTimeFrom(value);
|
|
@@ -3,6 +3,11 @@ import { type DefectId, type Repro } from "./repros.js";
|
|
|
3
3
|
export declare function runRepro(repro: Pick<Repro, "run">): string;
|
|
4
4
|
/** True when a repro's output is the spec-correct value, i.e. the installed runtime is fixed. */
|
|
5
5
|
export declare function reproPasses(repro: Pick<Repro, "expected">, output: string): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* True when any of `candidates` for this defect and Temporal calendar id fails. Stops at the first
|
|
8
|
+
* failure, so the order of a defect's repros is the order they are tried in.
|
|
9
|
+
*/
|
|
10
|
+
export declare function anyReproFails(candidates: readonly Repro[], defect: DefectId, calendar: string): boolean;
|
|
6
11
|
/**
|
|
7
12
|
* True when any repro for this defect and Temporal calendar id fails in the installed runtime.
|
|
8
13
|
* A calendar with no repro for the defect is not affected by it.
|
|
@@ -19,6 +24,27 @@ export declare function isDefectPresent(defect: DefectId, calendar: string): boo
|
|
|
19
24
|
* take the spec path through `isCalendarArithmeticCompatNeeded`.
|
|
20
25
|
*/
|
|
21
26
|
export declare function isNudgeWindowCompatNeeded(): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* True when this runtime matches a zoned string's offset by minutes even when the offset is
|
|
29
|
+
* written with seconds (defect D12).
|
|
30
|
+
*
|
|
31
|
+
* TC39 `ToTemporalZonedDateTime` matches by minutes only an offset with no seconds part; one
|
|
32
|
+
* written with seconds must equal the zone's offset exactly. A runtime that always matches by
|
|
33
|
+
* minutes accepts `-00:45:00[Africa/Monrovia]` for a zone at −00:44:30, and picks the wrong pass
|
|
34
|
+
* of a second repeated by a sub-minute transition (Pacific/Niue, 1952).
|
|
35
|
+
*/
|
|
36
|
+
export declare function isSecondsOffsetMatchCompatNeeded(): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* True when this runtime's time zone transition search cannot be trusted (defect D13).
|
|
39
|
+
*
|
|
40
|
+
* TC39 `GetNamedTimeZoneNextTransition` returns the first offset change after an instant. A runtime
|
|
41
|
+
* that samples the offset in steps longer than the gap between two changes skips a pair that
|
|
42
|
+
* returns to the same offset, and can loop for ever on three different offsets in one step. The
|
|
43
|
+
* skipped-pair repros come first and none of them can stall, so on such a runtime the probe
|
|
44
|
+
* answers before a stalling repro is reached. Every repro has to pass for the workaround to go
|
|
45
|
+
* dormant: a runtime that fixes the skipped pairs and still stalls on one zone keeps it.
|
|
46
|
+
*/
|
|
47
|
+
export declare function isTransitionSearchCompatNeeded(): boolean;
|
|
22
48
|
/**
|
|
23
49
|
* True when calendar arithmetic in `calendarId` needs the compat layer in this runtime: any of its
|
|
24
50
|
* add, until or read probes fails (CORE-6 spec §3.6.2). `iso8601` never does, and costs nothing.
|
|
@@ -21,6 +21,15 @@ export function runRepro(repro) {
|
|
|
21
21
|
export function reproPasses(repro, output) {
|
|
22
22
|
return output === repro.expected;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* True when any of `candidates` for this defect and Temporal calendar id fails. Stops at the first
|
|
26
|
+
* failure, so the order of a defect's repros is the order they are tried in.
|
|
27
|
+
*/
|
|
28
|
+
export function anyReproFails(candidates, defect, calendar) {
|
|
29
|
+
return candidates.some((repro) => repro.defect === defect &&
|
|
30
|
+
repro.calendar === calendar &&
|
|
31
|
+
!reproPasses(repro, runRepro(repro)));
|
|
32
|
+
}
|
|
24
33
|
const cache = new Map();
|
|
25
34
|
/**
|
|
26
35
|
* True when any repro for this defect and Temporal calendar id fails in the installed runtime.
|
|
@@ -32,9 +41,7 @@ export function isDefectPresent(defect, calendar) {
|
|
|
32
41
|
if (cached !== undefined) {
|
|
33
42
|
return cached;
|
|
34
43
|
}
|
|
35
|
-
const present = repros
|
|
36
|
-
repro.calendar === calendar &&
|
|
37
|
-
!reproPasses(repro, runRepro(repro)));
|
|
44
|
+
const present = anyReproFails(repros, defect, calendar);
|
|
38
45
|
cache.set(key, present);
|
|
39
46
|
return present;
|
|
40
47
|
}
|
|
@@ -51,6 +58,31 @@ export function isDefectPresent(defect, calendar) {
|
|
|
51
58
|
export function isNudgeWindowCompatNeeded() {
|
|
52
59
|
return isDefectPresent("D11", "iso8601");
|
|
53
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* True when this runtime matches a zoned string's offset by minutes even when the offset is
|
|
63
|
+
* written with seconds (defect D12).
|
|
64
|
+
*
|
|
65
|
+
* TC39 `ToTemporalZonedDateTime` matches by minutes only an offset with no seconds part; one
|
|
66
|
+
* written with seconds must equal the zone's offset exactly. A runtime that always matches by
|
|
67
|
+
* minutes accepts `-00:45:00[Africa/Monrovia]` for a zone at −00:44:30, and picks the wrong pass
|
|
68
|
+
* of a second repeated by a sub-minute transition (Pacific/Niue, 1952).
|
|
69
|
+
*/
|
|
70
|
+
export function isSecondsOffsetMatchCompatNeeded() {
|
|
71
|
+
return isDefectPresent("D12", "iso8601");
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* True when this runtime's time zone transition search cannot be trusted (defect D13).
|
|
75
|
+
*
|
|
76
|
+
* TC39 `GetNamedTimeZoneNextTransition` returns the first offset change after an instant. A runtime
|
|
77
|
+
* that samples the offset in steps longer than the gap between two changes skips a pair that
|
|
78
|
+
* returns to the same offset, and can loop for ever on three different offsets in one step. The
|
|
79
|
+
* skipped-pair repros come first and none of them can stall, so on such a runtime the probe
|
|
80
|
+
* answers before a stalling repro is reached. Every repro has to pass for the workaround to go
|
|
81
|
+
* dormant: a runtime that fixes the skipped pairs and still stalls on one zone keeps it.
|
|
82
|
+
*/
|
|
83
|
+
export function isTransitionSearchCompatNeeded() {
|
|
84
|
+
return isDefectPresent("D13", "iso8601");
|
|
85
|
+
}
|
|
54
86
|
/** Defects that make the runtime's calendar arithmetic or reads differ from the spec. */
|
|
55
87
|
const ARITHMETIC_DEFECTS = [
|
|
56
88
|
"D1",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
|
-
import { MAX_ISO_EPOCH_DAYS } from "../
|
|
2
|
+
import { MAX_ISO_EPOCH_DAYS } from "../epochNanoseconds.js";
|
|
3
3
|
import { calendarFieldsOf } from "./calendarFields.js";
|
|
4
4
|
/*
|
|
5
5
|
* Read-only fields → ISO search. Calendar fields increase strictly with ISO order under the key
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { type CalendarDateUnit, calendarDateAdd, calendarDateUntil, } from "./calendarDateArithmetic.js";
|
|
2
2
|
export { calendarDateFromFields } from "./calendarDateFromFields.js";
|
|
3
|
-
export { isCalendarArithmeticCompatNeeded, isNudgeWindowCompatNeeded, } from "./capabilities.js";
|
|
3
|
+
export { isCalendarArithmeticCompatNeeded, isNudgeWindowCompatNeeded, isSecondsOffsetMatchCompatNeeded, isTransitionSearchCompatNeeded, } from "./capabilities.js";
|
|
4
4
|
export { calendarFieldsOf } from "./calendarFields.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// The only import surface of the Temporal compat layer. See README.md.
|
|
2
2
|
export { calendarDateAdd, calendarDateUntil, } from "./calendarDateArithmetic.js";
|
|
3
3
|
export { calendarDateFromFields } from "./calendarDateFromFields.js";
|
|
4
|
-
export { isCalendarArithmeticCompatNeeded, isNudgeWindowCompatNeeded, } from "./capabilities.js";
|
|
4
|
+
export { isCalendarArithmeticCompatNeeded, isNudgeWindowCompatNeeded, isSecondsOffsetMatchCompatNeeded, isTransitionSearchCompatNeeded, } from "./capabilities.js";
|
|
5
5
|
export { calendarFieldsOf } from "./calendarFields.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Defect ids from the CORE-6 calendar-correctness spec §1.2. */
|
|
2
|
-
export type DefectId = "D1" | "D2" | "D3" | "D4" | "D5" | "D6" | "D7" | "D8" | "D10" | "D11";
|
|
2
|
+
export type DefectId = "D1" | "D2" | "D3" | "D4" | "D5" | "D6" | "D7" | "D8" | "D10" | "D11" | "D12" | "D13";
|
|
3
3
|
/**
|
|
4
4
|
* Zoned defects worked around in `internal/zonedWallClock*`: the range-limit defects (upstream
|
|
5
5
|
* issue drafts A, B and D in the CORE-6 polyfill research) and zoned.E, the transition search
|
|
@@ -498,6 +498,161 @@ const d9Repros = [
|
|
|
498
498
|
},
|
|
499
499
|
];
|
|
500
500
|
});
|
|
501
|
+
/** The epoch nanoseconds `Temporal.ZonedDateTime.from(item)` reads, or the error's name. */
|
|
502
|
+
function zonedStringEpoch(item) {
|
|
503
|
+
try {
|
|
504
|
+
return String(Temporal.ZonedDateTime.from(item).epochNanoseconds);
|
|
505
|
+
}
|
|
506
|
+
catch (error) {
|
|
507
|
+
return error instanceof Error ? error.name : "Error";
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* D12 (`internal/zonedWallClock.ts` defect 4): `ToTemporalZonedDateTime` matches a string's
|
|
512
|
+
* offset against the zone by minutes even when the offset is written with seconds, where TC39
|
|
513
|
+
* requires match-exactly ("If offsetParseResult contains more than one MinuteSecond Parse Node,
|
|
514
|
+
* set matchBehaviour to match-exactly"). Expected values: test262
|
|
515
|
+
* `test/intl402/Temporal/ZonedDateTime/from/zoneddatetime-sub-minute-offset.js` ("rounded
|
|
516
|
+
* HH:MM:SS not accepted in string offset (offset=reject)", and the Pacific/Niue edge case,
|
|
517
|
+
* "-11:20:00 is accepted as -11:20:00": `reference + 20_000_000_000n`). The test writes the
|
|
518
|
+
* Monrovia time as `T12`; `T12:00` is the same wall time.
|
|
519
|
+
*/
|
|
520
|
+
const d12Repros = [
|
|
521
|
+
{
|
|
522
|
+
defect: "D12",
|
|
523
|
+
calendar: "iso8601",
|
|
524
|
+
name: "roundedSecondsRejected",
|
|
525
|
+
expected: "RangeError",
|
|
526
|
+
run: () => zonedStringEpoch("1970-01-01T12:00-00:45:00[Africa/Monrovia]"),
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
defect: "D12",
|
|
530
|
+
calendar: "iso8601",
|
|
531
|
+
name: "exactSecondsSecondPass",
|
|
532
|
+
expected: "-543069601000000000",
|
|
533
|
+
run: () => zonedStringEpoch("1952-10-15T23:59:59-11:20:00[Pacific/Niue]"),
|
|
534
|
+
},
|
|
535
|
+
];
|
|
536
|
+
/** More `Intl.DateTimeFormat#format` reads than this for one transition lookup is a stalled search. */
|
|
537
|
+
const D13_INTL_READ_LIMIT = 20_000;
|
|
538
|
+
/**
|
|
539
|
+
* `run()`'s output, or a note when it made more than `D13_INTL_READ_LIMIT` reads through
|
|
540
|
+
* `Intl.DateTimeFormat.prototype.format`, where the read then throws so a search that would never
|
|
541
|
+
* return stops. Polyfill 0.5.1 reads every offset through that getter.
|
|
542
|
+
*/
|
|
543
|
+
function withBoundedOffsetReads(run) {
|
|
544
|
+
const prototype = Intl.DateTimeFormat.prototype;
|
|
545
|
+
const original = Object.getOwnPropertyDescriptor(prototype, "format");
|
|
546
|
+
const originalGet = original?.get;
|
|
547
|
+
if (original === undefined || originalGet === undefined) {
|
|
548
|
+
return "cannot bound Intl.DateTimeFormat#format";
|
|
549
|
+
}
|
|
550
|
+
let reads = 0;
|
|
551
|
+
Object.defineProperty(prototype, "format", {
|
|
552
|
+
configurable: true,
|
|
553
|
+
get() {
|
|
554
|
+
const format = originalGet.call(this);
|
|
555
|
+
return (date) => {
|
|
556
|
+
reads++;
|
|
557
|
+
if (reads > D13_INTL_READ_LIMIT) {
|
|
558
|
+
throw new RangeError(`more than ${D13_INTL_READ_LIMIT} offset reads`);
|
|
559
|
+
}
|
|
560
|
+
return format(date);
|
|
561
|
+
};
|
|
562
|
+
},
|
|
563
|
+
});
|
|
564
|
+
try {
|
|
565
|
+
return run();
|
|
566
|
+
}
|
|
567
|
+
finally {
|
|
568
|
+
Object.defineProperty(prototype, "format", original);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
/** America/Boa_Vista's 2000-10-08T04:00:00Z advance (−04:00 → −03:00, local midnight skipped). */
|
|
572
|
+
const BOA_VISTA_ADVANCE = "2000-10-08T01:00:00-03:00[America/Boa_Vista]";
|
|
573
|
+
/**
|
|
574
|
+
* D13 (`internal/zonedWallClock.ts` defect 5): `GetNamedTimeZoneNextTransition` and
|
|
575
|
+
* `…PreviousTransition` sample the offset every 14 days. Two changes inside one step that return
|
|
576
|
+
* to the same offset are skipped (America/Boa_Vista 2000-10-08 and 2000-10-15, 601,200 s apart),
|
|
577
|
+
* so `GetStartOfDay` for the skipped midnight of 2000-10-08 fails too; three different offsets in
|
|
578
|
+
* one step (Europe/Riga 1944-10-02 and 1944-10-12) make `bisect` loop for ever, its assertion
|
|
579
|
+
* compiled out. Spec: TC39 Temporal `GetNamedTimeZoneNextTransition`, "the smallest integer
|
|
580
|
+
* greater than epochNanoseconds" at which the offset changes. Expected values: Node 26.10.0's
|
|
581
|
+
* native Temporal and `zdump -v` (tz 2026c). The polyfill's main branch (a79c6a1, per-zone search
|
|
582
|
+
* windows, in no release) fixes the zones it lists but leaves `bisect` unchanged, and its 17-day
|
|
583
|
+
* window for Africa/El_Aaiun holds three offsets in 1976: `stall.nextElAaiun` covers that, so the
|
|
584
|
+
* workaround stays until every repro here passes.
|
|
585
|
+
*
|
|
586
|
+
* Order matters: the capability probe stops at the first failing repro, so the `skip.*` repros,
|
|
587
|
+
* which cannot stall, come before `stall.*`, which a runtime that fails them never runs in
|
|
588
|
+
* process. The canary runs `stall.*` under `withBoundedOffsetReads`.
|
|
589
|
+
*/
|
|
590
|
+
const d13Repros = [
|
|
591
|
+
{
|
|
592
|
+
defect: "D13",
|
|
593
|
+
calendar: "iso8601",
|
|
594
|
+
name: "skip.nextBoaVista",
|
|
595
|
+
expected: BOA_VISTA_ADVANCE,
|
|
596
|
+
run: () => String(Temporal.Instant.from("2000-10-01T12:00:00Z")
|
|
597
|
+
.toZonedDateTimeISO("America/Boa_Vista")
|
|
598
|
+
.getTimeZoneTransition("next")),
|
|
599
|
+
},
|
|
600
|
+
{
|
|
601
|
+
defect: "D13",
|
|
602
|
+
calendar: "iso8601",
|
|
603
|
+
name: "skip.previousBoaVista",
|
|
604
|
+
expected: "2000-10-14T23:00:00-04:00[America/Boa_Vista]",
|
|
605
|
+
run: () => String(Temporal.Instant.from("2000-10-20T12:00:00Z")
|
|
606
|
+
.toZonedDateTimeISO("America/Boa_Vista")
|
|
607
|
+
.getTimeZoneTransition("previous")),
|
|
608
|
+
},
|
|
609
|
+
{
|
|
610
|
+
defect: "D13",
|
|
611
|
+
calendar: "iso8601",
|
|
612
|
+
name: "skip.startOfDayBoaVista",
|
|
613
|
+
expected: BOA_VISTA_ADVANCE,
|
|
614
|
+
run: () => String(Temporal.PlainDate.from("2000-10-08").toZonedDateTime("America/Boa_Vista")),
|
|
615
|
+
},
|
|
616
|
+
{
|
|
617
|
+
defect: "D13",
|
|
618
|
+
calendar: "iso8601",
|
|
619
|
+
name: "skip.hoursInDayNoronha",
|
|
620
|
+
expected: "23",
|
|
621
|
+
run: () => String(Temporal.ZonedDateTime.from("2000-10-08T12:00[America/Noronha]")
|
|
622
|
+
.hoursInDay),
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
defect: "D13",
|
|
626
|
+
calendar: "iso8601",
|
|
627
|
+
name: "stall.nextRiga",
|
|
628
|
+
expected: "1944-10-02T02:00:00+01:00[Europe/Riga]",
|
|
629
|
+
run: () => withBoundedOffsetReads(() => String(Temporal.Instant.from("1944-04-15T12:00:00Z")
|
|
630
|
+
.toZonedDateTimeISO("Europe/Riga")
|
|
631
|
+
.getTimeZoneTransition("next"))),
|
|
632
|
+
},
|
|
633
|
+
{
|
|
634
|
+
defect: "D13",
|
|
635
|
+
calendar: "iso8601",
|
|
636
|
+
name: "stall.nextSimferopol",
|
|
637
|
+
expected: "1944-04-03T03:00:00+02:00[Europe/Simferopol]",
|
|
638
|
+
run: () => withBoundedOffsetReads(() => String(Temporal.Instant.from("1943-10-15T12:00:00Z")
|
|
639
|
+
.toZonedDateTimeISO("Europe/Simferopol")
|
|
640
|
+
.getTimeZoneTransition("next"))),
|
|
641
|
+
},
|
|
642
|
+
// js-temporal main (a79c6a1) gives Africa/El_Aaiun a 17-day search window. Its changes of
|
|
643
|
+
// 1976-04-14T01:00:00Z (−01:00 → +00:00) and 1976-05-01T00:00:00Z (+00:00 → +01:00) are 16.958
|
|
644
|
+
// days apart, so one window holds three offsets and `bisect`, unchanged there, cannot narrow.
|
|
645
|
+
// 0.5.1's 14-day step passes these two; a release with a79c6a1 alone would not.
|
|
646
|
+
...["1976-04-14T00:30:00Z", "1976-03-28T00:30:00Z"].map((from) => ({
|
|
647
|
+
defect: "D13",
|
|
648
|
+
calendar: "iso8601",
|
|
649
|
+
name: `stall.nextElAaiun ${from}`,
|
|
650
|
+
expected: "1976-04-14T01:00:00+00:00[Africa/El_Aaiun]",
|
|
651
|
+
run: () => withBoundedOffsetReads(() => String(Temporal.Instant.from(from)
|
|
652
|
+
.toZonedDateTimeISO("Africa/El_Aaiun")
|
|
653
|
+
.getTimeZoneTransition("next"))),
|
|
654
|
+
})),
|
|
655
|
+
];
|
|
501
656
|
export const repros = [
|
|
502
657
|
...d9Repros,
|
|
503
658
|
...zonedARepros,
|
|
@@ -508,6 +663,8 @@ export const repros = [
|
|
|
508
663
|
...d1ArithmeticRepros,
|
|
509
664
|
d1RelativeToRepro,
|
|
510
665
|
...d10Repros,
|
|
666
|
+
...d12Repros,
|
|
667
|
+
...d13Repros,
|
|
511
668
|
...d6Repros,
|
|
512
669
|
d7Repro,
|
|
513
670
|
d7LeapMonthEndRepro,
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { TimestampClass } from "../types/index.js";
|
|
2
|
+
/** A validated `TimestampEvent`, with both of its moments as epoch nanoseconds. */
|
|
3
|
+
export type ParsedTimestampEvent = {
|
|
4
|
+
classifier: TimestampClass;
|
|
5
|
+
/** The event's `at`, exactly as the caller wrote it. */
|
|
6
|
+
at: string;
|
|
7
|
+
atNanoseconds: bigint;
|
|
8
|
+
recordedNanoseconds: bigint;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Validate a list of `TimestampEvent`s and put them in recording order, or `null`.
|
|
12
|
+
*
|
|
13
|
+
* The shared reading behind `bestAvailable` and `estimateDrift`:
|
|
14
|
+
*
|
|
15
|
+
* - Every event must be an object whose `classifier` is exactly `PLN`, `EST`, `REQ` or `ACT` and
|
|
16
|
+
* whose `at` and `recordedAt` are instants (`Z`/offset) or zoned strings, read as
|
|
17
|
+
* `parseInstantNanoseconds` reads them: the offset fixes the instant, a minute-rounded offset
|
|
18
|
+
* is read as its bracketed zone's real offset, and the bracket is otherwise not checked. One
|
|
19
|
+
* invalid event makes the whole list invalid.
|
|
20
|
+
* - The result is sorted by `recordedAt`, earliest first. Events recorded at the same instant
|
|
21
|
+
* keep their input order, so of two ties the later index is the later record.
|
|
22
|
+
* - `at` is kept exactly as written, so a caller can echo it.
|
|
23
|
+
* - An empty list is `[]`; the caller decides what that means.
|
|
24
|
+
* - A hostile value (a throwing getter, a revoked Proxy) is invalid input: `null`, never a throw.
|
|
25
|
+
*
|
|
26
|
+
* @param events candidate list of timestamp events
|
|
27
|
+
* @returns the events in recording order with their instants, or null on invalid input
|
|
28
|
+
*
|
|
29
|
+
* @example parseTimestampEvents([]) // []
|
|
30
|
+
* @example parseTimestampEvents([{ classifier: "ETA", at: "2024-06-15T12:00:00Z", recordedAt: "2024-06-15T10:00:00Z" }]) // null
|
|
31
|
+
*/
|
|
32
|
+
export declare function parseTimestampEvents(events: unknown): ParsedTimestampEvent[] | null;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { parseInstantNanoseconds } from "./instantNanoseconds.js";
|
|
2
|
+
import { isObject } from "./isObject.js";
|
|
3
|
+
const TIMESTAMP_CLASSES = new Set([
|
|
4
|
+
"PLN",
|
|
5
|
+
"EST",
|
|
6
|
+
"REQ",
|
|
7
|
+
"ACT",
|
|
8
|
+
]);
|
|
9
|
+
/** One event validated, or `null`. */
|
|
10
|
+
function parseEvent(event) {
|
|
11
|
+
if (!isObject(event)) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
const { classifier, at, recordedAt } = event;
|
|
15
|
+
if (!TIMESTAMP_CLASSES.has(classifier) || typeof at !== "string") {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const atNanoseconds = parseInstantNanoseconds(at);
|
|
19
|
+
const recordedNanoseconds = parseInstantNanoseconds(recordedAt);
|
|
20
|
+
if (atNanoseconds === null || recordedNanoseconds === null) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
classifier: classifier,
|
|
25
|
+
at,
|
|
26
|
+
atNanoseconds,
|
|
27
|
+
recordedNanoseconds,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Validate a list of `TimestampEvent`s and put them in recording order, or `null`.
|
|
32
|
+
*
|
|
33
|
+
* The shared reading behind `bestAvailable` and `estimateDrift`:
|
|
34
|
+
*
|
|
35
|
+
* - Every event must be an object whose `classifier` is exactly `PLN`, `EST`, `REQ` or `ACT` and
|
|
36
|
+
* whose `at` and `recordedAt` are instants (`Z`/offset) or zoned strings, read as
|
|
37
|
+
* `parseInstantNanoseconds` reads them: the offset fixes the instant, a minute-rounded offset
|
|
38
|
+
* is read as its bracketed zone's real offset, and the bracket is otherwise not checked. One
|
|
39
|
+
* invalid event makes the whole list invalid.
|
|
40
|
+
* - The result is sorted by `recordedAt`, earliest first. Events recorded at the same instant
|
|
41
|
+
* keep their input order, so of two ties the later index is the later record.
|
|
42
|
+
* - `at` is kept exactly as written, so a caller can echo it.
|
|
43
|
+
* - An empty list is `[]`; the caller decides what that means.
|
|
44
|
+
* - A hostile value (a throwing getter, a revoked Proxy) is invalid input: `null`, never a throw.
|
|
45
|
+
*
|
|
46
|
+
* @param events candidate list of timestamp events
|
|
47
|
+
* @returns the events in recording order with their instants, or null on invalid input
|
|
48
|
+
*
|
|
49
|
+
* @example parseTimestampEvents([]) // []
|
|
50
|
+
* @example parseTimestampEvents([{ classifier: "ETA", at: "2024-06-15T12:00:00Z", recordedAt: "2024-06-15T10:00:00Z" }]) // null
|
|
51
|
+
*/
|
|
52
|
+
export function parseTimestampEvents(events) {
|
|
53
|
+
try {
|
|
54
|
+
if (!Array.isArray(events)) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
const parsed = [];
|
|
58
|
+
for (const event of events) {
|
|
59
|
+
const one = parseEvent(event);
|
|
60
|
+
if (one === null) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
parsed.push(one);
|
|
64
|
+
}
|
|
65
|
+
// Array.prototype.sort is stable, so ties keep their input order.
|
|
66
|
+
return parsed.sort((a, b) => a.recordedNanoseconds < b.recordedNanoseconds
|
|
67
|
+
? -1
|
|
68
|
+
: a.recordedNanoseconds > b.recordedNanoseconds
|
|
69
|
+
? 1
|
|
70
|
+
: 0);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// A hostile value (a throwing getter, a revoked Proxy) is invalid input.
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
/**
|
|
3
3
|
* Read a UTC ISO string as a zoned date-time for the `parse*FromUtc` accessors: the instant it
|
|
4
|
-
* names, on the wall clock of `options.timeZone
|
|
5
|
-
*
|
|
4
|
+
* names, on the wall clock of `options.timeZone`. The utc twin of `unixZonedDateTime`.
|
|
5
|
+
*
|
|
6
|
+
* - `timeZone` defaults to `"UTC"`; `"local"` is the system zone; an unknown zone is invalid
|
|
7
|
+
* (see `normalizeTimeZone`).
|
|
6
8
|
*
|
|
7
9
|
* @param value UTC ISO 8601 datetime string
|
|
8
10
|
* @param options optional `{ timeZone }`
|
|
9
11
|
* @returns the zoned date-time, or null when the value or the zone is invalid
|
|
10
12
|
* @example utcZonedDateTime("2024-03-15T14:30:00Z", { timeZone: "Asia/Tokyo" })?.toString() // "2024-03-15T23:30:00+09:00[Asia/Tokyo]"
|
|
13
|
+
* @example utcZonedDateTime("2024-03-15T14:30:00Z", { timeZone: "local" })?.timeZoneId // the system zone, e.g. "America/New_York"
|
|
11
14
|
* @example utcZonedDateTime("2024-03-15T14:30:00Z", { timeZone: "Invalid/Zone" }) // null
|
|
12
15
|
* @example utcZonedDateTime("2024-03-15T14:30:00") // null (no Z)
|
|
13
16
|
*/
|
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import { isValidUtc } from "../utc/validate/isValidUtc.js";
|
|
3
|
-
import {
|
|
3
|
+
import { normalizeTimeZone } from "./normalizeTimeZone.js";
|
|
4
4
|
/**
|
|
5
5
|
* Read a UTC ISO string as a zoned date-time for the `parse*FromUtc` accessors: the instant it
|
|
6
|
-
* names, on the wall clock of `options.timeZone
|
|
7
|
-
*
|
|
6
|
+
* names, on the wall clock of `options.timeZone`. The utc twin of `unixZonedDateTime`.
|
|
7
|
+
*
|
|
8
|
+
* - `timeZone` defaults to `"UTC"`; `"local"` is the system zone; an unknown zone is invalid
|
|
9
|
+
* (see `normalizeTimeZone`).
|
|
8
10
|
*
|
|
9
11
|
* @param value UTC ISO 8601 datetime string
|
|
10
12
|
* @param options optional `{ timeZone }`
|
|
11
13
|
* @returns the zoned date-time, or null when the value or the zone is invalid
|
|
12
14
|
* @example utcZonedDateTime("2024-03-15T14:30:00Z", { timeZone: "Asia/Tokyo" })?.toString() // "2024-03-15T23:30:00+09:00[Asia/Tokyo]"
|
|
15
|
+
* @example utcZonedDateTime("2024-03-15T14:30:00Z", { timeZone: "local" })?.timeZoneId // the system zone, e.g. "America/New_York"
|
|
13
16
|
* @example utcZonedDateTime("2024-03-15T14:30:00Z", { timeZone: "Invalid/Zone" }) // null
|
|
14
17
|
* @example utcZonedDateTime("2024-03-15T14:30:00") // null (no Z)
|
|
15
18
|
*/
|
|
16
19
|
export function utcZonedDateTime(value, options) {
|
|
17
20
|
if (!isValidUtc(value))
|
|
18
21
|
return null;
|
|
19
|
-
const timeZone =
|
|
20
|
-
if (timeZone ===
|
|
22
|
+
const timeZone = normalizeTimeZone(options?.timeZone);
|
|
23
|
+
if (timeZone === "")
|
|
21
24
|
return null;
|
|
22
25
|
try {
|
|
23
26
|
return Temporal.Instant.from(value).toZonedDateTimeISO(timeZone);
|
|
@@ -160,12 +160,13 @@ function truncatedWallClockUntil(from, to, unit) {
|
|
|
160
160
|
* `zoned - 1 ns` is `zoned` itself exactly when a transition sits on it. At the first
|
|
161
161
|
* representable instant there is no `zoned - 1 ns`, and nothing earlier, so that check is skipped.
|
|
162
162
|
*/
|
|
163
|
-
function transitionAtOrBefore(zoned) {
|
|
163
|
+
function transitionAtOrBefore(zoned, notBefore) {
|
|
164
164
|
try {
|
|
165
165
|
if (transitionSitsOn(zoned)) {
|
|
166
166
|
return zoned;
|
|
167
167
|
}
|
|
168
|
-
|
|
168
|
+
// The caller ignores a transition before `notBefore`, so the search stops there.
|
|
169
|
+
return zonedPreviousTransition(zoned, notBefore.epochNanoseconds - 1n);
|
|
169
170
|
}
|
|
170
171
|
catch {
|
|
171
172
|
return null;
|
|
@@ -180,7 +181,7 @@ function transitionSitsOn(zoned) {
|
|
|
180
181
|
catch {
|
|
181
182
|
return false;
|
|
182
183
|
}
|
|
183
|
-
const next = zonedNextTransition(justBefore);
|
|
184
|
+
const next = zonedNextTransition(justBefore, zoned.epochNanoseconds);
|
|
184
185
|
return next !== null && next.toInstant().equals(zoned.toInstant());
|
|
185
186
|
}
|
|
186
187
|
/** Units whose buckets are labelled by a local date: a repeated wall time inside one stays one bucket. */
|
|
@@ -250,7 +251,7 @@ export function zonedUnitStart(zoned, unit, weekStartsOn = 1) {
|
|
|
250
251
|
let start = boundaryInOwnOffset(zoned, unit, weekStartsOn);
|
|
251
252
|
let cursor = zoned;
|
|
252
253
|
for (let i = 0; i < MAX_TRANSITION_WALKBACK; i++) {
|
|
253
|
-
const transition = transitionAtOrBefore(cursor);
|
|
254
|
+
const transition = transitionAtOrBefore(cursor, start);
|
|
254
255
|
// A transition exactly on `start` is still checked: Havana's second 00:00 is a unit-aligned
|
|
255
256
|
// own-offset start that the day runs straight through.
|
|
256
257
|
if (!transition || Temporal.ZonedDateTime.compare(transition, start) < 0) {
|
|
@@ -325,7 +326,8 @@ export function nextZonedBucketStart(current, unit, weekStartsOn = 1) {
|
|
|
325
326
|
let cursor = current;
|
|
326
327
|
for (let i = 0; i < MAX_TRANSITION_WALKBACK; i++) {
|
|
327
328
|
const boundary = nextBoundaryWithinRange(cursor, unit, weekStartsOn);
|
|
328
|
-
|
|
329
|
+
// A transition after the boundary changes nothing, so the search stops there.
|
|
330
|
+
const transition = zonedNextTransition(cursor, boundary?.epochNanoseconds);
|
|
329
331
|
if (!transition ||
|
|
330
332
|
(boundary !== null &&
|
|
331
333
|
Temporal.ZonedDateTime.compare(transition, boundary) > 0)) {
|
|
@@ -423,7 +425,7 @@ export function countZonedBuckets(start, end, unit, weekStartsOn = 1) {
|
|
|
423
425
|
let runStart = startOfStart;
|
|
424
426
|
let cursor = startOfStart;
|
|
425
427
|
for (let i = 0; i < MAX_COUNTED_TRANSITIONS; i++) {
|
|
426
|
-
const transition = zonedNextTransition(cursor)?.withCalendar(start.calendarId) ?? null;
|
|
428
|
+
const transition = zonedNextTransition(cursor, startOfEnd.epochNanoseconds)?.withCalendar(start.calendarId) ?? null;
|
|
427
429
|
if (!transition ||
|
|
428
430
|
Temporal.ZonedDateTime.compare(transition, startOfEnd) > 0) {
|
|
429
431
|
return (spanned +
|
|
@@ -44,7 +44,7 @@ export function countZonedLocalDates(start, end) {
|
|
|
44
44
|
const ranges = [];
|
|
45
45
|
let runStart = start;
|
|
46
46
|
for (let i = 0; i <= MAX_WALKED_TRANSITIONS; i++) {
|
|
47
|
-
const transition = zonedNextTransition(runStart);
|
|
47
|
+
const transition = zonedNextTransition(runStart, end.epochNanoseconds);
|
|
48
48
|
const isLastRun = transition === null ||
|
|
49
49
|
Temporal.ZonedDateTime.compare(transition, end) > 0;
|
|
50
50
|
const runEnd = isLastRun ? end : transition.subtract({ nanoseconds: 1 });
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The sampling step: 5 days. It must stay under the smallest gap between two offset changes of
|
|
3
|
+
* one zone, 601,200 s in tz 2026c (`zdump -v`, America/Boa_Vista 2000-10-08 to 2000-10-15).
|
|
4
|
+
*/
|
|
5
|
+
export declare const TRANSITION_SEARCH_STEP_NANOSECONDS: bigint;
|
|
6
|
+
/**
|
|
7
|
+
* TC39 `GetNamedTimeZoneNextTransition`: the first offset change strictly after `from`.
|
|
8
|
+
*
|
|
9
|
+
* @param timeZone a named zone
|
|
10
|
+
* @param from the instant to search after (exclusive)
|
|
11
|
+
* @param until optional: the last instant to search (inclusive); a later change returns null
|
|
12
|
+
* @returns the change's epoch nanoseconds, or null when there is none up to `until` or none within
|
|
13
|
+
* three years of the later of `from` and the current instant
|
|
14
|
+
* @throws RangeError past `MAX_SEARCH_STEPS` steps
|
|
15
|
+
*/
|
|
16
|
+
export declare function nextTransitionAfter(timeZone: string, from: bigint, until?: bigint): bigint | null;
|
|
17
|
+
/**
|
|
18
|
+
* TC39 `GetNamedTimeZonePreviousTransition`: the last offset change strictly before `from`.
|
|
19
|
+
*
|
|
20
|
+
* @param timeZone a named zone
|
|
21
|
+
* @param from the instant to search before (exclusive)
|
|
22
|
+
* @param since optional: the search stops here (exclusive); an earlier change returns null
|
|
23
|
+
* @returns the change's epoch nanoseconds, or null when there is none after `since`, or, with no
|
|
24
|
+
* `since`, none at all
|
|
25
|
+
* @throws RangeError past `MAX_SEARCH_STEPS` steps or `MAX_TABLED_TRANSITIONS` tabled changes
|
|
26
|
+
*/
|
|
27
|
+
export declare function previousTransitionBefore(timeZone: string, from: bigint, since?: bigint): bigint | null;
|