@northguild/gmt 1.18.0 → 1.19.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 +55 -2920
- package/dist/calendar/calculate/bucketRange.d.ts +10 -2
- package/dist/calendar/calculate/bucketRange.js +18 -61
- package/dist/calendar/calculate/floorToZone.d.ts +10 -2
- package/dist/calendar/calculate/floorToZone.js +15 -7
- package/dist/calendar/hours/addOperatingTime.d.ts +6 -0
- package/dist/calendar/hours/addOperatingTime.js +7 -1
- package/dist/calendar/hours/isOpenAt.d.ts +6 -0
- package/dist/calendar/hours/isOpenAt.js +6 -0
- package/dist/calendar/hours/nextCloseAt.d.ts +6 -0
- package/dist/calendar/hours/nextCloseAt.js +7 -1
- package/dist/calendar/hours/nextOpenAt.d.ts +6 -0
- package/dist/calendar/hours/nextOpenAt.js +7 -1
- package/dist/calendar/hours/operatingIntervals.d.ts +5 -0
- package/dist/calendar/hours/operatingIntervals.js +5 -0
- package/dist/calendar/hours/operatingTimeBetween.d.ts +5 -0
- package/dist/calendar/hours/operatingTimeBetween.js +5 -0
- package/dist/calendar/hours/recurringWindows.d.ts +8 -1
- package/dist/calendar/hours/recurringWindows.js +12 -4
- package/dist/duration/calculate/durationFromUnits.d.ts +47 -0
- package/dist/duration/calculate/durationFromUnits.js +67 -0
- package/dist/duration/calculate/getDurationUnit.d.ts +2 -2
- package/dist/duration/calculate/getDurationUnit.js +2 -2
- package/dist/duration/calculate/index.d.ts +3 -1
- package/dist/duration/calculate/index.js +3 -1
- package/dist/duration/calculate/negateDuration.d.ts +1 -1
- package/dist/duration/calculate/negateDuration.js +1 -1
- package/dist/duration/calculate/{durationAs.d.ts → totalDuration.d.ts} +25 -19
- package/dist/duration/calculate/{durationAs.js → totalDuration.js} +25 -19
- package/dist/duration/calculate/totalUnits.d.ts +49 -0
- package/dist/duration/calculate/totalUnits.js +73 -0
- package/dist/duration/compare/compareDurations.d.ts +1 -1
- package/dist/duration/compare/compareDurations.js +1 -1
- package/dist/duty/calculate/dutyDayFor.d.ts +38 -0
- package/dist/duty/calculate/dutyDayFor.js +71 -0
- package/dist/duty/calculate/dutyTotals.d.ts +24 -0
- package/dist/duty/calculate/dutyTotals.js +41 -0
- package/dist/duty/calculate/dutyViolations.d.ts +74 -0
- package/dist/duty/calculate/dutyViolations.js +65 -0
- package/dist/duty/calculate/evaluateDutyLog.d.ts +77 -0
- package/dist/duty/calculate/evaluateDutyLog.js +75 -0
- package/dist/duty/calculate/index.d.ts +7 -0
- package/dist/duty/calculate/index.js +7 -0
- package/dist/duty/calculate/longestRun.d.ts +28 -0
- package/dist/duty/calculate/longestRun.js +54 -0
- package/dist/duty/calculate/qualifyingRestPairs.d.ts +37 -0
- package/dist/duty/calculate/qualifyingRestPairs.js +58 -0
- package/dist/duty/calculate/qualifyingRests.d.ts +27 -0
- package/dist/duty/calculate/qualifyingRests.js +49 -0
- package/dist/duty/index.d.ts +3 -0
- package/dist/duty/index.js +4 -0
- package/dist/duty/validate/index.d.ts +1 -0
- package/dist/duty/validate/index.js +1 -0
- package/dist/duty/validate/isValidDutyLog.d.ts +24 -0
- package/dist/duty/validate/isValidDutyLog.js +34 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/instant/convert/classifyLocal.d.ts +5 -1
- package/dist/instant/convert/classifyLocal.js +16 -6
- package/dist/instant/convert/fromOffsetInstant.d.ts +4 -0
- package/dist/instant/convert/fromOffsetInstant.js +6 -1
- package/dist/instant/convert/resolveLocal.d.ts +7 -2
- package/dist/instant/convert/resolveLocal.js +16 -8
- package/dist/instant/convert/toOffsetInstant.d.ts +12 -8
- package/dist/instant/convert/toOffsetInstant.js +19 -11
- package/dist/instant/index.d.ts +1 -0
- package/dist/instant/index.js +1 -0
- package/dist/instant/validate/index.d.ts +1 -0
- package/dist/instant/validate/index.js +1 -0
- package/dist/instant/validate/isValidUtcOffset.d.ts +32 -0
- package/dist/instant/validate/isValidUtcOffset.js +35 -0
- package/dist/intermodal/calculate/chargeableDays.d.ts +6 -0
- package/dist/intermodal/calculate/chargeableDays.js +12 -4
- package/dist/intermodal/calculate/freeTimeExpiry.d.ts +7 -0
- package/dist/intermodal/calculate/freeTimeExpiry.js +15 -4
- package/dist/intermodal/calculate/index.d.ts +1 -0
- package/dist/intermodal/calculate/index.js +1 -0
- package/dist/intermodal/calculate/multimodalETA.d.ts +76 -0
- package/dist/intermodal/calculate/multimodalETA.js +145 -0
- package/dist/intermodal/format/bolTimestamp.d.ts +76 -0
- package/dist/intermodal/format/bolTimestamp.js +78 -0
- package/dist/intermodal/format/formatEdifactDate.d.ts +34 -0
- package/dist/intermodal/format/formatEdifactDate.js +42 -0
- package/dist/intermodal/format/formatEdifactDatePeriod.d.ts +35 -0
- package/dist/intermodal/format/formatEdifactDatePeriod.js +43 -0
- package/dist/intermodal/format/formatEdifactDateTime.d.ts +37 -0
- package/dist/intermodal/format/formatEdifactDateTime.js +45 -0
- package/dist/intermodal/format/formatEdifactDateTimePeriod.d.ts +40 -0
- package/dist/intermodal/format/formatEdifactDateTimePeriod.js +48 -0
- package/dist/intermodal/format/formatEdifactOffsetDateTime.d.ts +62 -0
- package/dist/intermodal/format/formatEdifactOffsetDateTime.js +70 -0
- package/dist/intermodal/format/formatEdifactTime.d.ts +35 -0
- package/dist/intermodal/format/formatEdifactTime.js +43 -0
- package/dist/intermodal/format/formatEpcisEvent.d.ts +47 -0
- package/dist/intermodal/format/formatEpcisEvent.js +79 -0
- package/dist/intermodal/format/formatX12Date.d.ts +35 -0
- package/dist/intermodal/format/formatX12Date.js +43 -0
- package/dist/intermodal/format/formatX12DateRange.d.ts +37 -0
- package/dist/intermodal/format/formatX12DateRange.js +45 -0
- package/dist/intermodal/format/formatX12DateTime.d.ts +39 -0
- package/dist/intermodal/format/formatX12DateTime.js +47 -0
- package/dist/intermodal/format/formatX12DateTimeRange.d.ts +40 -0
- package/dist/intermodal/format/formatX12DateTimeRange.js +48 -0
- package/dist/intermodal/format/formatX12Time.d.ts +42 -0
- package/dist/intermodal/format/formatX12Time.js +50 -0
- package/dist/intermodal/format/formatX12TimeElement.d.ts +46 -0
- package/dist/intermodal/format/formatX12TimeElement.js +54 -0
- package/dist/intermodal/format/index.d.ts +14 -0
- package/dist/intermodal/format/index.js +14 -0
- package/dist/intermodal/index.d.ts +3 -0
- package/dist/intermodal/index.js +3 -0
- package/dist/intermodal/parse/classifyEdifactDtmFormat.d.ts +48 -0
- package/dist/intermodal/parse/classifyEdifactDtmFormat.js +55 -0
- package/dist/intermodal/parse/classifyX12DateTimePeriodFormat.d.ts +50 -0
- package/dist/intermodal/parse/classifyX12DateTimePeriodFormat.js +57 -0
- package/dist/intermodal/parse/classifyX12TimeCode.d.ts +46 -0
- package/dist/intermodal/parse/classifyX12TimeCode.js +57 -0
- package/dist/intermodal/parse/index.d.ts +18 -0
- package/dist/intermodal/parse/index.js +18 -0
- package/dist/intermodal/parse/parseEdifactDate.d.ts +37 -0
- package/dist/intermodal/parse/parseEdifactDate.js +45 -0
- package/dist/intermodal/parse/parseEdifactDatePeriod.d.ts +43 -0
- package/dist/intermodal/parse/parseEdifactDatePeriod.js +51 -0
- package/dist/intermodal/parse/parseEdifactDateTime.d.ts +43 -0
- package/dist/intermodal/parse/parseEdifactDateTime.js +51 -0
- package/dist/intermodal/parse/parseEdifactDateTimePeriod.d.ts +45 -0
- package/dist/intermodal/parse/parseEdifactDateTimePeriod.js +53 -0
- package/dist/intermodal/parse/parseEdifactOffsetDateTime.d.ts +60 -0
- package/dist/intermodal/parse/parseEdifactOffsetDateTime.js +68 -0
- package/dist/intermodal/parse/parseEdifactTime.d.ts +37 -0
- package/dist/intermodal/parse/parseEdifactTime.js +45 -0
- package/dist/intermodal/parse/parseEpcisEvent.d.ts +95 -0
- package/dist/intermodal/parse/parseEpcisEvent.js +102 -0
- package/dist/intermodal/parse/parseX12Date.d.ts +39 -0
- package/dist/intermodal/parse/parseX12Date.js +47 -0
- package/dist/intermodal/parse/parseX12DateAndTime.d.ts +52 -0
- package/dist/intermodal/parse/parseX12DateAndTime.js +61 -0
- package/dist/intermodal/parse/parseX12DateRange.d.ts +44 -0
- package/dist/intermodal/parse/parseX12DateRange.js +52 -0
- package/dist/intermodal/parse/parseX12DateTime.d.ts +45 -0
- package/dist/intermodal/parse/parseX12DateTime.js +53 -0
- package/dist/intermodal/parse/parseX12DateTimeRange.d.ts +46 -0
- package/dist/intermodal/parse/parseX12DateTimeRange.js +54 -0
- package/dist/intermodal/parse/parseX12Time.d.ts +65 -0
- package/dist/intermodal/parse/parseX12Time.js +77 -0
- package/dist/intermodal/parse/x12TimeCodeOffset.d.ts +57 -0
- package/dist/intermodal/parse/x12TimeCodeOffset.js +110 -0
- package/dist/intermodal/parse/x12TimeCodeZone.d.ts +57 -0
- package/dist/intermodal/parse/x12TimeCodeZone.js +105 -0
- package/dist/intermodal/validate/index.d.ts +18 -0
- package/dist/intermodal/validate/index.js +18 -0
- package/dist/intermodal/validate/isValidEdifactDate.d.ts +26 -0
- package/dist/intermodal/validate/isValidEdifactDate.js +28 -0
- package/dist/intermodal/validate/isValidEdifactDatePeriod.d.ts +28 -0
- package/dist/intermodal/validate/isValidEdifactDatePeriod.js +30 -0
- package/dist/intermodal/validate/isValidEdifactDateTime.d.ts +30 -0
- package/dist/intermodal/validate/isValidEdifactDateTime.js +32 -0
- package/dist/intermodal/validate/isValidEdifactDateTimePeriod.d.ts +28 -0
- package/dist/intermodal/validate/isValidEdifactDateTimePeriod.js +30 -0
- package/dist/intermodal/validate/isValidEdifactDtmFormat.d.ts +39 -0
- package/dist/intermodal/validate/isValidEdifactDtmFormat.js +42 -0
- package/dist/intermodal/validate/isValidEdifactOffsetDateTime.d.ts +36 -0
- package/dist/intermodal/validate/isValidEdifactOffsetDateTime.js +38 -0
- package/dist/intermodal/validate/isValidEdifactTime.d.ts +28 -0
- package/dist/intermodal/validate/isValidEdifactTime.js +30 -0
- package/dist/intermodal/validate/isValidEpcisEvent.d.ts +41 -0
- package/dist/intermodal/validate/isValidEpcisEvent.js +58 -0
- package/dist/intermodal/validate/isValidEpcisEventTime.d.ts +33 -0
- package/dist/intermodal/validate/isValidEpcisEventTime.js +48 -0
- package/dist/intermodal/validate/isValidEpcisTimeZoneOffset.d.ts +30 -0
- package/dist/intermodal/validate/isValidEpcisTimeZoneOffset.js +38 -0
- package/dist/intermodal/validate/isValidX12Date.d.ts +28 -0
- package/dist/intermodal/validate/isValidX12Date.js +30 -0
- package/dist/intermodal/validate/isValidX12DateAndTime.d.ts +32 -0
- package/dist/intermodal/validate/isValidX12DateAndTime.js +35 -0
- package/dist/intermodal/validate/isValidX12DateRange.d.ts +29 -0
- package/dist/intermodal/validate/isValidX12DateRange.js +31 -0
- package/dist/intermodal/validate/isValidX12DateTime.d.ts +30 -0
- package/dist/intermodal/validate/isValidX12DateTime.js +32 -0
- package/dist/intermodal/validate/isValidX12DateTimePeriodFormat.d.ts +43 -0
- package/dist/intermodal/validate/isValidX12DateTimePeriodFormat.js +46 -0
- package/dist/intermodal/validate/isValidX12DateTimeRange.d.ts +31 -0
- package/dist/intermodal/validate/isValidX12DateTimeRange.js +33 -0
- package/dist/intermodal/validate/isValidX12Time.d.ts +38 -0
- package/dist/intermodal/validate/isValidX12Time.js +40 -0
- package/dist/intermodal/validate/isValidX12TimeCode.d.ts +38 -0
- package/dist/intermodal/validate/isValidX12TimeCode.js +41 -0
- package/dist/internal/businessCalendar.js +4 -9
- package/dist/internal/dutyEngine.d.ts +125 -0
- package/dist/internal/dutyEngine.js +1746 -0
- package/dist/internal/dutyLog.d.ts +27 -0
- package/dist/internal/dutyLog.js +47 -0
- package/dist/internal/dutyPeriods.d.ts +135 -0
- package/dist/internal/dutyPeriods.js +369 -0
- package/dist/internal/dutyRules.d.ts +197 -0
- package/dist/internal/dutyRules.js +484 -0
- package/dist/internal/ediDateTimeFields.d.ts +97 -0
- package/dist/internal/ediDateTimeFields.js +288 -0
- package/dist/internal/ediDateTimeWriter.d.ts +92 -0
- package/dist/internal/ediDateTimeWriter.js +298 -0
- package/dist/internal/ediGrammar.d.ts +158 -0
- package/dist/internal/ediGrammar.js +384 -0
- package/dist/internal/englishCalendarNames.d.ts +3 -1
- package/dist/internal/englishCalendarNames.js +3 -1
- package/dist/internal/freeTimeLedger.d.ts +5 -0
- package/dist/internal/freeTimeLedger.js +11 -2
- package/dist/internal/index.d.ts +5 -2
- package/dist/internal/index.js +9 -2
- package/dist/internal/intervalNanoseconds.js +2 -1
- package/dist/internal/isObject.d.ts +13 -6
- package/dist/internal/isObject.js +14 -7
- package/dist/internal/isoYearString.d.ts +21 -0
- package/dist/internal/isoYearString.js +27 -0
- package/dist/internal/maxPieces.js +2 -1
- package/dist/internal/normalizeTimeZone.d.ts +4 -1
- package/dist/internal/normalizeTimeZone.js +4 -1
- package/dist/internal/operatingSchedule.d.ts +13 -4
- package/dist/internal/operatingSchedule.js +146 -58
- package/dist/internal/patternToken.d.ts +10 -3
- package/dist/internal/patternToken.js +31 -12
- package/dist/internal/readDurationUnits.d.ts +34 -0
- package/dist/internal/readDurationUnits.js +78 -0
- package/dist/internal/readSetFields.d.ts +50 -0
- package/dist/internal/readSetFields.js +179 -0
- package/dist/internal/resolveRelativeUnit.d.ts +1 -1
- package/dist/internal/resolveRelativeUnit.js +1 -1
- package/dist/internal/resolveUnixIntervalPair.d.ts +8 -2
- package/dist/internal/resolveUnixIntervalPair.js +11 -7
- package/dist/internal/startOrEndOfUnix.d.ts +2 -1
- package/dist/internal/startOrEndOfUnix.js +9 -6
- package/dist/internal/twoDigitYear.d.ts +19 -0
- package/dist/internal/twoDigitYear.js +22 -0
- package/dist/internal/unixEpochValue.js +3 -2
- package/dist/internal/unixWallClock.d.ts +24 -0
- package/dist/internal/unixWallClock.js +35 -0
- package/dist/internal/utcWallClock.d.ts +20 -0
- package/dist/internal/utcWallClock.js +32 -0
- package/dist/internal/yearWindowStart.d.ts +28 -0
- package/dist/internal/yearWindowStart.js +52 -0
- package/dist/internal/zoneBucketCap.d.ts +18 -0
- package/dist/internal/zoneBucketCap.js +64 -0
- package/dist/internal/zoneFrame.d.ts +180 -0
- package/dist/internal/zoneFrame.js +221 -0
- package/dist/internal/zonedNowUnitValue.d.ts +7 -4
- package/dist/internal/zonedNowUnitValue.js +8 -4
- package/dist/internal/zonedWallClockDifference.js +4 -4
- package/dist/internal/zonedWallClockOperations.d.ts +5 -2
- package/dist/internal/zonedWallClockOperations.js +7 -10
- package/dist/plain/calculate/addDate.js +4 -7
- package/dist/plain/calculate/addDateTime.js +4 -7
- package/dist/plain/calculate/addTime.js +4 -7
- package/dist/plain/calculate/endOfTime.d.ts +1 -1
- package/dist/plain/calculate/setDate.d.ts +20 -3
- package/dist/plain/calculate/setDate.js +27 -7
- package/dist/plain/calculate/setDateTime.d.ts +15 -3
- package/dist/plain/calculate/setDateTime.js +22 -7
- package/dist/plain/calculate/setTime.d.ts +13 -1
- package/dist/plain/calculate/setTime.js +21 -6
- package/dist/plain/calculate/startOfTime.d.ts +1 -1
- package/dist/plain/calculate/subtractDate.js +4 -7
- package/dist/plain/calculate/subtractDateTime.js +4 -7
- package/dist/plain/calculate/subtractTime.js +4 -7
- package/dist/plain/format/formatCalendar.js +2 -1
- package/dist/plain/format/formatRelativeDate.js +2 -1
- package/dist/plain/format/formatRelativeDateTime.js +2 -1
- package/dist/plain/format/formatRelativeTime.js +2 -1
- package/dist/plain/format/{formatSql.d.ts → formatSqlDateTime.d.ts} +7 -7
- package/dist/plain/format/{formatSql.js → formatSqlDateTime.js} +7 -7
- package/dist/plain/format/index.d.ts +1 -1
- package/dist/plain/format/index.js +1 -1
- package/dist/plain/get/getNowUnit.d.ts +2 -0
- package/dist/plain/get/getNowUnit.js +2 -0
- package/dist/plain/get/getYear.d.ts +2 -0
- package/dist/plain/get/getYear.js +4 -3
- package/dist/plain/interval/intervalXorAllDate.js +2 -2
- package/dist/plain/interval/intervalXorAllDateTime.js +2 -2
- package/dist/plain/interval/intervalXorAllTime.js +2 -2
- package/dist/plain/interval/mergeIntervalsDate.js +2 -2
- package/dist/plain/interval/mergeIntervalsDateTime.js +2 -2
- package/dist/plain/interval/mergeIntervalsTime.js +2 -2
- package/dist/plain/parse/index.d.ts +1 -1
- package/dist/plain/parse/index.js +1 -1
- package/dist/plain/parse/parseDateTimeWithPattern.d.ts +16 -3
- package/dist/plain/parse/parseDateTimeWithPattern.js +20 -5
- package/dist/plain/parse/parseDateWithPattern.d.ts +17 -3
- package/dist/plain/parse/parseDateWithPattern.js +21 -5
- package/dist/plain/parse/{parseSql.d.ts → parseSqlDateTime.d.ts} +8 -8
- package/dist/plain/parse/{parseSql.js → parseSqlDateTime.js} +8 -8
- package/dist/plain/parse/parseTimeWithPattern.js +1 -0
- package/dist/plain/parse/parseUnitFromDate.d.ts +3 -0
- package/dist/plain/parse/parseUnitFromDate.js +5 -1
- package/dist/plain/parse/parseUnitFromDateTime.d.ts +3 -0
- package/dist/plain/parse/parseUnitFromDateTime.js +5 -1
- package/dist/plain/parse/parseYearFromDate.d.ts +5 -2
- package/dist/plain/parse/parseYearFromDate.js +7 -3
- package/dist/plain/parse/parseYearFromDateTime.d.ts +4 -2
- package/dist/plain/parse/parseYearFromDateTime.js +6 -3
- package/dist/plain/validate/index.d.ts +1 -0
- package/dist/plain/validate/index.js +1 -0
- package/dist/plain/validate/isValidSqlDateTime.d.ts +33 -0
- package/dist/plain/validate/isValidSqlDateTime.js +36 -0
- package/dist/precision/convert/fromNanoseconds.d.ts +9 -3
- package/dist/precision/convert/fromNanoseconds.js +9 -3
- package/dist/regex/epcis.d.ts +60 -0
- package/dist/regex/epcis.js +60 -0
- package/dist/regex/http-date.d.ts +6 -4
- package/dist/regex/http-date.js +6 -4
- package/dist/regex/index.d.ts +1 -0
- package/dist/regex/index.js +1 -0
- package/dist/regex/rfc-2822.d.ts +2 -0
- package/dist/regex/rfc-2822.js +2 -0
- package/dist/regex/rfc-3339.d.ts +3 -1
- package/dist/regex/rfc-3339.js +3 -1
- package/dist/regex/sql-date-time.d.ts +2 -1
- package/dist/regex/sql-date-time.js +2 -1
- package/dist/regex/time-zone-like.d.ts +3 -2
- package/dist/regex/time-zone-like.js +3 -2
- package/dist/regex/utc-offset.d.ts +2 -1
- package/dist/regex/utc-offset.js +2 -1
- package/dist/transport/calculate/crossingTime.d.ts +6 -1
- package/dist/transport/calculate/crossingTime.js +6 -1
- package/dist/transport/calculate/cutoffAt.d.ts +6 -1
- package/dist/transport/calculate/cutoffAt.js +2 -0
- package/dist/transport/calculate/cutoffSchedule.d.ts +6 -1
- package/dist/transport/calculate/cutoffSchedule.js +2 -0
- package/dist/transport/calculate/dwellTime.d.ts +6 -1
- package/dist/transport/calculate/dwellTime.js +6 -1
- package/dist/transport/calculate/scheduleDelivery.d.ts +13 -5
- package/dist/transport/calculate/scheduleDelivery.js +6 -1
- package/dist/transport/convert/etaAtZone.d.ts +6 -1
- package/dist/transport/convert/etaAtZone.js +6 -1
- package/dist/types/business-calendar.d.ts +5 -4
- package/dist/types/duty.d.ts +777 -0
- package/dist/types/duty.js +0 -0
- package/dist/types/edi.d.ts +407 -0
- package/dist/types/edi.js +0 -0
- package/dist/types/epcis.d.ts +25 -0
- package/dist/types/epcis.js +0 -0
- package/dist/types/exact-duration-unit.d.ts +8 -0
- package/dist/types/exact-duration-unit.js +0 -0
- package/dist/types/free-time-options.d.ts +4 -3
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.js +5 -0
- package/dist/types/operating-schedule.d.ts +3 -2
- package/dist/types/two-digit-year.d.ts +23 -0
- package/dist/types/two-digit-year.js +0 -0
- package/dist/types/zone-bucket-unit.d.ts +1 -1
- package/dist/unix/calculate/addUnix.d.ts +11 -2
- package/dist/unix/calculate/addUnix.js +14 -11
- package/dist/unix/calculate/diffUnix.d.ts +10 -2
- package/dist/unix/calculate/diffUnix.js +11 -6
- package/dist/unix/calculate/diffUnixAsDuration.d.ts +10 -2
- package/dist/unix/calculate/diffUnixAsDuration.js +10 -5
- package/dist/unix/calculate/endOfQuarterForUnix.d.ts +10 -2
- package/dist/unix/calculate/endOfQuarterForUnix.js +6 -0
- package/dist/unix/calculate/endOfUnix.d.ts +11 -2
- package/dist/unix/calculate/endOfUnix.js +7 -0
- package/dist/unix/calculate/isBetweenUnix.d.ts +3 -2
- package/dist/unix/calculate/isBetweenUnix.js +3 -3
- package/dist/unix/calculate/roundUnix.d.ts +10 -2
- package/dist/unix/calculate/roundUnix.js +13 -6
- package/dist/unix/calculate/setUnix.d.ts +25 -5
- package/dist/unix/calculate/setUnix.js +33 -12
- package/dist/unix/calculate/startOfQuarterForUnix.d.ts +10 -2
- package/dist/unix/calculate/startOfQuarterForUnix.js +6 -0
- package/dist/unix/calculate/startOfUnix.d.ts +11 -2
- package/dist/unix/calculate/startOfUnix.js +7 -0
- package/dist/unix/calculate/subtractUnix.d.ts +10 -2
- package/dist/unix/calculate/subtractUnix.js +13 -11
- package/dist/unix/compare/areUnixEqualBy.d.ts +11 -2
- package/dist/unix/compare/areUnixEqualBy.js +7 -0
- package/dist/unix/convert/convertUnixToPlainDate.d.ts +5 -2
- package/dist/unix/convert/convertUnixToPlainDate.js +5 -4
- package/dist/unix/convert/convertUnixToPlainDateTime.d.ts +5 -2
- package/dist/unix/convert/convertUnixToPlainDateTime.js +5 -4
- package/dist/unix/convert/convertUnixToPlainTime.d.ts +5 -2
- package/dist/unix/convert/convertUnixToPlainTime.js +5 -4
- package/dist/unix/convert/convertUnixToZoned.d.ts +5 -1
- package/dist/unix/convert/convertUnixToZoned.js +5 -1
- package/dist/unix/format/formatCalendarUnix.d.ts +6 -2
- package/dist/unix/format/formatCalendarUnix.js +6 -1
- package/dist/unix/format/formatRelativeUnix.d.ts +11 -3
- package/dist/unix/format/formatRelativeUnix.js +13 -5
- package/dist/unix/format/formatUnix.d.ts +7 -2
- package/dist/unix/format/formatUnix.js +4 -0
- package/dist/unix/get/getUnixDay.d.ts +1 -3
- package/dist/unix/get/getUnixDay.js +5 -12
- package/dist/unix/get/getUnixHour.d.ts +1 -3
- package/dist/unix/get/getUnixHour.js +5 -12
- package/dist/unix/get/getUnixMicrosecond.d.ts +1 -3
- package/dist/unix/get/getUnixMicrosecond.js +4 -11
- package/dist/unix/get/getUnixMillisecond.d.ts +1 -3
- package/dist/unix/get/getUnixMillisecond.js +5 -12
- package/dist/unix/get/getUnixMinute.d.ts +1 -3
- package/dist/unix/get/getUnixMinute.js +5 -12
- package/dist/unix/get/getUnixMonth.d.ts +1 -3
- package/dist/unix/get/getUnixMonth.js +5 -12
- package/dist/unix/get/getUnixNanosecond.d.ts +1 -3
- package/dist/unix/get/getUnixNanosecond.js +4 -11
- package/dist/unix/get/getUnixNowUnit.d.ts +2 -0
- package/dist/unix/get/getUnixNowUnit.js +2 -0
- package/dist/unix/get/getUnixSecond.d.ts +1 -3
- package/dist/unix/get/getUnixSecond.js +5 -12
- package/dist/unix/get/getUnixYear.d.ts +3 -3
- package/dist/unix/get/getUnixYear.js +5 -12
- package/dist/unix/interval/intervalCountUnix.d.ts +11 -2
- package/dist/unix/interval/intervalCountUnix.js +7 -0
- package/dist/unix/interval/intervalFromDurationUnix.d.ts +10 -2
- package/dist/unix/interval/intervalFromDurationUnix.js +12 -7
- package/dist/unix/interval/intervalLengthUnix.d.ts +10 -2
- package/dist/unix/interval/intervalLengthUnix.js +6 -0
- package/dist/unix/interval/intervalOverlappingDaysUnix.d.ts +10 -2
- package/dist/unix/interval/intervalOverlappingDaysUnix.js +10 -5
- package/dist/unix/interval/splitIntervalByUnitUnix.d.ts +10 -2
- package/dist/unix/interval/splitIntervalByUnitUnix.js +12 -6
- package/dist/unix/parse/parseDateFromUnix.d.ts +4 -2
- package/dist/unix/parse/parseDateFromUnix.js +3 -3
- package/dist/unix/parse/parseDayFromUnix.d.ts +4 -2
- package/dist/unix/parse/parseDayOfWeekFromUnix.d.ts +4 -2
- package/dist/unix/parse/parseDayOfWeekFromUnix.js +2 -2
- package/dist/unix/parse/parseHourFromUnix.d.ts +4 -2
- package/dist/unix/parse/parseMicrosecondFromUnix.d.ts +4 -2
- package/dist/unix/parse/parseMillisecondFromUnix.d.ts +4 -2
- package/dist/unix/parse/parseMinuteFromUnix.d.ts +4 -2
- package/dist/unix/parse/parseMonthFromUnix.d.ts +4 -2
- package/dist/unix/parse/parseNanosecondFromUnix.d.ts +4 -2
- package/dist/unix/parse/parseSecondFromUnix.d.ts +4 -2
- package/dist/unix/parse/parseTimeFromUnix.d.ts +5 -2
- package/dist/unix/parse/parseTimeFromUnix.js +4 -3
- package/dist/unix/parse/parseUnitFromUnix.d.ts +9 -3
- package/dist/unix/parse/parseUnitFromUnix.js +21 -14
- package/dist/unix/parse/parseWeekFromUnix.d.ts +3 -2
- package/dist/unix/parse/parseWeekFromUnix.js +4 -4
- package/dist/unix/parse/parseYearFromUnix.d.ts +8 -3
- package/dist/unix/parse/parseYearFromUnix.js +4 -1
- package/dist/unix/validate/isValidUnixUnit.d.ts +1 -1
- package/dist/utc/calculate/addUtc.js +4 -7
- package/dist/utc/calculate/setUtc.d.ts +16 -3
- package/dist/utc/calculate/setUtc.js +22 -8
- package/dist/utc/calculate/subtractUtc.js +4 -7
- package/dist/utc/convert/convertUtcToPlainDate.d.ts +8 -2
- package/dist/utc/convert/convertUtcToPlainDate.js +10 -7
- package/dist/utc/convert/convertUtcToPlainDateTime.d.ts +9 -2
- package/dist/utc/convert/convertUtcToPlainDateTime.js +12 -13
- package/dist/utc/convert/convertUtcToPlainTime.d.ts +5 -2
- package/dist/utc/convert/convertUtcToPlainTime.js +7 -6
- package/dist/utc/convert/convertUtcToZoned.d.ts +5 -1
- package/dist/utc/convert/convertUtcToZoned.js +5 -1
- package/dist/utc/format/formatCalendarUtc.d.ts +6 -2
- package/dist/utc/format/formatCalendarUtc.js +6 -1
- package/dist/utc/format/{formatHttp.d.ts → formatHttpDate.d.ts} +7 -7
- package/dist/utc/format/{formatHttp.js → formatHttpDate.js} +7 -7
- package/dist/utc/format/formatRelativeUtc.d.ts +11 -3
- package/dist/utc/format/formatRelativeUtc.js +13 -5
- package/dist/utc/format/formatUtc.d.ts +7 -2
- package/dist/utc/format/formatUtc.js +4 -0
- package/dist/utc/format/index.d.ts +1 -1
- package/dist/utc/format/index.js +1 -1
- package/dist/utc/get/getUtcDay.d.ts +1 -3
- package/dist/utc/get/getUtcDay.js +5 -12
- package/dist/utc/get/getUtcHour.d.ts +1 -3
- package/dist/utc/get/getUtcHour.js +5 -12
- package/dist/utc/get/getUtcMicrosecond.d.ts +1 -3
- package/dist/utc/get/getUtcMicrosecond.js +4 -11
- package/dist/utc/get/getUtcMillisecond.d.ts +1 -3
- package/dist/utc/get/getUtcMillisecond.js +5 -12
- package/dist/utc/get/getUtcMinute.d.ts +1 -3
- package/dist/utc/get/getUtcMinute.js +5 -12
- package/dist/utc/get/getUtcMonth.d.ts +1 -3
- package/dist/utc/get/getUtcMonth.js +5 -12
- package/dist/utc/get/getUtcNanosecond.d.ts +1 -3
- package/dist/utc/get/getUtcNanosecond.js +4 -11
- package/dist/utc/get/getUtcNow.d.ts +1 -3
- package/dist/utc/get/getUtcNow.js +2 -9
- package/dist/utc/get/getUtcNowUnit.d.ts +2 -0
- package/dist/utc/get/getUtcNowUnit.js +2 -0
- package/dist/utc/get/getUtcSecond.d.ts +1 -3
- package/dist/utc/get/getUtcSecond.js +5 -12
- package/dist/utc/get/getUtcYear.d.ts +3 -3
- package/dist/utc/get/getUtcYear.js +5 -12
- package/dist/utc/interval/intervalXorAllUtc.js +2 -2
- package/dist/utc/interval/mergeIntervalsUtc.js +2 -2
- package/dist/utc/parse/index.d.ts +1 -1
- package/dist/utc/parse/index.js +1 -1
- package/dist/utc/parse/parseDateFromUtc.d.ts +4 -2
- package/dist/utc/parse/parseDateFromUtc.js +2 -2
- package/dist/utc/parse/parseDayFromUtc.d.ts +4 -2
- package/dist/utc/parse/parseDayFromUtc.js +2 -2
- package/dist/utc/parse/parseDayOfWeekFromUtc.d.ts +4 -2
- package/dist/utc/parse/parseDayOfWeekFromUtc.js +4 -4
- package/dist/utc/parse/parseHourFromUtc.d.ts +4 -2
- package/dist/utc/parse/parseHourFromUtc.js +2 -2
- package/dist/utc/parse/{parseHttp.d.ts → parseHttpDate.d.ts} +12 -12
- package/dist/utc/parse/{parseHttp.js → parseHttpDate.js} +12 -12
- package/dist/utc/parse/parseMicrosecondFromUtc.d.ts +4 -2
- package/dist/utc/parse/parseMicrosecondFromUtc.js +2 -2
- package/dist/utc/parse/parseMillisecondFromUtc.d.ts +4 -2
- package/dist/utc/parse/parseMillisecondFromUtc.js +2 -2
- package/dist/utc/parse/parseMinuteFromUtc.d.ts +4 -2
- package/dist/utc/parse/parseMinuteFromUtc.js +2 -2
- package/dist/utc/parse/parseMonthFromUtc.d.ts +4 -2
- package/dist/utc/parse/parseMonthFromUtc.js +2 -2
- package/dist/utc/parse/parseNanosecondFromUtc.d.ts +4 -2
- package/dist/utc/parse/parseNanosecondFromUtc.js +2 -2
- package/dist/utc/parse/parseSecondFromUtc.d.ts +4 -2
- package/dist/utc/parse/parseSecondFromUtc.js +2 -2
- package/dist/utc/parse/parseTimeFromUtc.d.ts +5 -2
- package/dist/utc/parse/parseTimeFromUtc.js +5 -4
- package/dist/utc/parse/parseUnitFromUtc.d.ts +10 -3
- package/dist/utc/parse/parseUnitFromUtc.js +11 -5
- package/dist/utc/parse/parseWeekFromUtc.d.ts +4 -2
- package/dist/utc/parse/parseWeekFromUtc.js +4 -4
- package/dist/utc/parse/parseYearFromUtc.d.ts +8 -4
- package/dist/utc/parse/parseYearFromUtc.js +8 -5
- package/dist/utc/validate/index.d.ts +2 -0
- package/dist/utc/validate/index.js +2 -0
- package/dist/utc/validate/isValidHttpDate.d.ts +35 -0
- package/dist/utc/validate/isValidHttpDate.js +38 -0
- package/dist/utc/validate/isValidUtc.d.ts +4 -0
- package/dist/utc/validate/isValidUtc.js +4 -0
- package/dist/utc/validate/isValidUtcTimestamp.d.ts +43 -0
- package/dist/utc/validate/isValidUtcTimestamp.js +48 -0
- package/dist/zoned/calculate/addZoned.js +4 -7
- package/dist/zoned/calculate/setZoned.d.ts +19 -5
- package/dist/zoned/calculate/setZoned.js +26 -9
- package/dist/zoned/calculate/subtractZoned.js +4 -7
- package/dist/zoned/convert/convertPlainDateTimeToZoned.d.ts +4 -1
- package/dist/zoned/convert/convertPlainDateTimeToZoned.js +4 -1
- package/dist/zoned/convert/convertZonedToZoned.d.ts +5 -1
- package/dist/zoned/convert/convertZonedToZoned.js +5 -1
- package/dist/zoned/format/formatCalendarZoned.js +2 -1
- package/dist/zoned/format/formatRelativeZoned.js +2 -1
- package/dist/zoned/format/formatTimeZoneName.d.ts +5 -1
- package/dist/zoned/format/formatTimeZoneName.js +5 -1
- package/dist/zoned/get/getDstTransitions.d.ts +5 -3
- package/dist/zoned/get/getDstTransitions.js +12 -7
- package/dist/zoned/get/getSystemTimeZone.d.ts +3 -1
- package/dist/zoned/get/getSystemTimeZone.js +5 -2
- package/dist/zoned/get/getTimeZoneOffset.d.ts +10 -2
- package/dist/zoned/get/getTimeZoneOffset.js +18 -5
- package/dist/zoned/get/getZonedDay.d.ts +2 -1
- package/dist/zoned/get/getZonedDay.js +6 -7
- package/dist/zoned/get/getZonedDayOfWeek.d.ts +2 -1
- package/dist/zoned/get/getZonedDayOfWeek.js +6 -5
- package/dist/zoned/get/getZonedHour.d.ts +2 -1
- package/dist/zoned/get/getZonedHour.js +6 -7
- package/dist/zoned/get/getZonedMicrosecond.d.ts +2 -1
- package/dist/zoned/get/getZonedMicrosecond.js +6 -5
- package/dist/zoned/get/getZonedMillisecond.d.ts +2 -1
- package/dist/zoned/get/getZonedMillisecond.js +6 -7
- package/dist/zoned/get/getZonedMinute.d.ts +2 -1
- package/dist/zoned/get/getZonedMinute.js +6 -7
- package/dist/zoned/get/getZonedMonth.d.ts +2 -1
- package/dist/zoned/get/getZonedMonth.js +6 -7
- package/dist/zoned/get/getZonedNanosecond.d.ts +2 -1
- package/dist/zoned/get/getZonedNanosecond.js +6 -5
- package/dist/zoned/get/getZonedNow.d.ts +5 -1
- package/dist/zoned/get/getZonedNow.js +5 -1
- package/dist/zoned/get/getZonedNowUnit.d.ts +6 -3
- package/dist/zoned/get/getZonedNowUnit.js +10 -7
- package/dist/zoned/get/getZonedSecond.d.ts +2 -1
- package/dist/zoned/get/getZonedSecond.js +6 -7
- package/dist/zoned/get/getZonedToday.d.ts +2 -1
- package/dist/zoned/get/getZonedToday.js +6 -5
- package/dist/zoned/get/getZonedWeekOfYear.d.ts +2 -1
- package/dist/zoned/get/getZonedWeekOfYear.js +6 -5
- package/dist/zoned/get/getZonedYear.d.ts +4 -1
- package/dist/zoned/get/getZonedYear.js +9 -7
- package/dist/zoned/interval/intervalXorAllZoned.js +2 -2
- package/dist/zoned/interval/mergeIntervalsZoned.js +2 -2
- package/dist/zoned/parse/parseUnitFromZoned.d.ts +4 -1
- package/dist/zoned/parse/parseUnitFromZoned.js +5 -1
- package/dist/zoned/parse/parseYearFromZoned.d.ts +4 -2
- package/dist/zoned/parse/parseYearFromZoned.js +6 -3
- package/dist/zoned/validate/hasDaylightSaving.d.ts +4 -2
- package/dist/zoned/validate/hasDaylightSaving.js +13 -7
- package/dist/zoned/validate/index.d.ts +2 -0
- package/dist/zoned/validate/index.js +2 -0
- package/dist/zoned/validate/isValidRfc2822DateTime.d.ts +32 -0
- package/dist/zoned/validate/isValidRfc2822DateTime.js +35 -0
- package/dist/zoned/validate/isValidRfc3339DateTime.d.ts +31 -0
- package/dist/zoned/validate/isValidRfc3339DateTime.js +34 -0
- package/dist/zoned/validate/isValidTimeZone.d.ts +5 -1
- package/dist/zoned/validate/isValidTimeZone.js +6 -2
- package/package.json +50 -1
- package/skills/gmt-arithmetic/SKILL.md +99 -12
- package/skills/gmt-basics/SKILL.md +57 -15
- package/skills/gmt-integration/SKILL.md +24 -9
- package/skills/gmt-timezone/SKILL.md +134 -29
- package/dist/internal/unixZonedDateTime.d.ts +0 -22
- package/dist/internal/unixZonedDateTime.js +0 -32
- package/dist/internal/utcZonedDateTime.d.ts +0 -19
- package/dist/internal/utcZonedDateTime.js +0 -31
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
2
|
+
import { readDurationUnits } from "../../internal/index.js";
|
|
3
|
+
import { isValidDateTimeDurationUnit } from "../../plain/validate/index.js";
|
|
4
|
+
/**
|
|
5
|
+
* Write an amount given as a unit object, such as `{ minutes: 15 }`, as an ISO 8601 duration
|
|
6
|
+
* string.
|
|
7
|
+
*
|
|
8
|
+
* - Uses Temporal.Duration.from to read the fields, then .toString() to write them.
|
|
9
|
+
* - Which function to use: `durationFromUnits` turns a unit object into the duration string that
|
|
10
|
+
* the other duration functions take. `totalUnits` totals a unit object of exact units in one
|
|
11
|
+
* call. `totalDuration` totals a duration string.
|
|
12
|
+
* - Takes all ten units, from years down to nanoseconds: writing a year, a month or a week needs
|
|
13
|
+
* no date to measure from. To total a calendar amount, pass the result to `totalDuration` with
|
|
14
|
+
* `relativeTo`.
|
|
15
|
+
* - Years down to minutes are written as given, and nothing is carried into a larger unit:
|
|
16
|
+
* `{ minutes: 90 }` is "PT90M". `normalizeDuration` with `largestUnit` carries it.
|
|
17
|
+
* - Seconds, milliseconds, microseconds and nanoseconds are written together as one decimal
|
|
18
|
+
* number of seconds, as Temporal's `Duration.prototype.toString` writes them:
|
|
19
|
+
* `{ milliseconds: 1500 }` is "PT1.5S". Reading that string back gives 1 second and 500
|
|
20
|
+
* milliseconds.
|
|
21
|
+
* - A zero amount is "PT0S", the one spelling Temporal writes for every zero duration.
|
|
22
|
+
* - Every key is a unit name in the plural, and every amount is a whole finite number. All
|
|
23
|
+
* nonzero amounts share one sign, as Temporal requires of a duration. A unit set to `undefined`
|
|
24
|
+
* is absent, as Temporal reads it.
|
|
25
|
+
* - An unknown key returns "", even beside a valid one. Temporal on its own ignores an unknown
|
|
26
|
+
* key, so a misspelt `{ minutes: 15, hour: 1 }` would be written "PT15M" with no warning.
|
|
27
|
+
* - Returns "" on an object with no unit, a non-object `units` (a duration string included), an
|
|
28
|
+
* invalid amount, or an amount past Temporal's duration range.
|
|
29
|
+
*
|
|
30
|
+
* @param units Partial<Record<DateTimeDurationUnit, number>> object holding the amount to write
|
|
31
|
+
* @returns ISO 8601 duration string, or "" on invalid input
|
|
32
|
+
*
|
|
33
|
+
* @example durationFromUnits({ minutes: 15 }) // "PT15M"
|
|
34
|
+
* @example durationFromUnits({ days: 1, hours: 12 }) // "P1DT12H"
|
|
35
|
+
* @example durationFromUnits({ minutes: 90 }) // "PT90M" (not carried into hours)
|
|
36
|
+
* @example durationFromUnits({ years: 1, months: 2 }) // "P1Y2M"
|
|
37
|
+
* @example durationFromUnits({ weeks: 1 }) // "P1W"
|
|
38
|
+
* @example durationFromUnits({ milliseconds: 1500 }) // "PT1.5S"
|
|
39
|
+
* @example durationFromUnits({ seconds: 59, milliseconds: 1500 }) // "PT60.5S" (one decimal number of seconds)
|
|
40
|
+
* @example durationFromUnits({ minutes: 15, hours: undefined }) // "PT15M" (an undefined unit is absent)
|
|
41
|
+
* @example durationFromUnits({ minutes: -15 }) // "-PT15M"
|
|
42
|
+
* @example durationFromUnits({ minutes: 0 }) // "PT0S"
|
|
43
|
+
* @example durationFromUnits({ minutes: 15, hour: 1 }) // "" (unknown key "hour")
|
|
44
|
+
* @example durationFromUnits({ minutes: 1.5 }) // "" (fractional amount)
|
|
45
|
+
* @example durationFromUnits({ hours: 1, minutes: -30 }) // "" (mixed signs)
|
|
46
|
+
* @example durationFromUnits({}) // ""
|
|
47
|
+
* @example durationFromUnits("PT15M") // "" (already a duration string)
|
|
48
|
+
*/
|
|
49
|
+
export function durationFromUnits(units) {
|
|
50
|
+
try {
|
|
51
|
+
const amounts = readDurationUnits(units, isValidDateTimeDurationUnit);
|
|
52
|
+
if (amounts === null) {
|
|
53
|
+
return "";
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
return Temporal.Duration.from(amounts).toString();
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return "";
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// Never throws (Core Rule 3): a hostile
|
|
64
|
+
// argument is invalid input, not an exception.
|
|
65
|
+
return "";
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -5,10 +5,10 @@ import type { DateTimeDurationUnit } from "../../types/index.js";
|
|
|
5
5
|
*
|
|
6
6
|
* - Uses Temporal.Duration.from and reads the named field directly — this is the value as
|
|
7
7
|
* *stored*, not a converted total: getDurationUnit("PT90M", "hours") is 0, because "PT90M"
|
|
8
|
-
* holds 90 in its minutes field and nothing in its hours field. Use `
|
|
8
|
+
* holds 90 in its minutes field and nothing in its hours field. Use `totalDuration` for a
|
|
9
9
|
* converted total.
|
|
10
10
|
* - Never needs `relativeTo`: reading a field is not a unit conversion, so calendar units
|
|
11
|
-
* (years/months/weeks) work here even though they require an anchor in `
|
|
11
|
+
* (years/months/weeks) work here even though they require an anchor in `totalDuration`.
|
|
12
12
|
* - Temporal balances fractional units at parse time, so getDurationUnit("PT1.5H", "minutes")
|
|
13
13
|
* is 30 — the input's own precision, not the caller's spelling of it, decides the fields.
|
|
14
14
|
* - A negative duration stores *every* field as negative, so this returns a negative number
|
|
@@ -7,10 +7,10 @@ import { resolveDurationUnit } from "../../internal/resolveDurationUnit.js";
|
|
|
7
7
|
*
|
|
8
8
|
* - Uses Temporal.Duration.from and reads the named field directly — this is the value as
|
|
9
9
|
* *stored*, not a converted total: getDurationUnit("PT90M", "hours") is 0, because "PT90M"
|
|
10
|
-
* holds 90 in its minutes field and nothing in its hours field. Use `
|
|
10
|
+
* holds 90 in its minutes field and nothing in its hours field. Use `totalDuration` for a
|
|
11
11
|
* converted total.
|
|
12
12
|
* - Never needs `relativeTo`: reading a field is not a unit conversion, so calendar units
|
|
13
|
-
* (years/months/weeks) work here even though they require an anchor in `
|
|
13
|
+
* (years/months/weeks) work here even though they require an anchor in `totalDuration`.
|
|
14
14
|
* - Temporal balances fractional units at parse time, so getDurationUnit("PT1.5H", "minutes")
|
|
15
15
|
* is 30 — the input's own precision, not the caller's spelling of it, decides the fields.
|
|
16
16
|
* - A negative duration stores *every* field as negative, so this returns a negative number
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export * from "./absDuration.js";
|
|
2
2
|
export * from "./addDuration.js";
|
|
3
|
-
export * from "./
|
|
3
|
+
export * from "./durationFromUnits.js";
|
|
4
4
|
export * from "./getDurationSign.js";
|
|
5
5
|
export * from "./getDurationUnit.js";
|
|
6
6
|
export * from "./negateDuration.js";
|
|
7
7
|
export * from "./subtractDuration.js";
|
|
8
|
+
export * from "./totalDuration.js";
|
|
9
|
+
export * from "./totalUnits.js";
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export * from "./absDuration.js";
|
|
2
2
|
export * from "./addDuration.js";
|
|
3
|
-
export * from "./
|
|
3
|
+
export * from "./durationFromUnits.js";
|
|
4
4
|
export * from "./getDurationSign.js";
|
|
5
5
|
export * from "./getDurationUnit.js";
|
|
6
6
|
export * from "./negateDuration.js";
|
|
7
7
|
export * from "./subtractDuration.js";
|
|
8
|
+
export * from "./totalDuration.js";
|
|
9
|
+
export * from "./totalUnits.js";
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* - Uses Temporal.Duration.from and .negated, then .toString() to re-emit.
|
|
5
5
|
* - Negating is a pure sign flip on every component, so it never needs `relativeTo` —
|
|
6
|
-
* calendar-unit durations round-trip through it fine, unlike `addDuration`/`
|
|
6
|
+
* calendar-unit durations round-trip through it fine, unlike `addDuration`/`totalDuration`.
|
|
7
7
|
* - A zero-length duration has no sign to flip and comes back as "PT0S", the canonical
|
|
8
8
|
* spelling Temporal emits for every zero duration (so "P0D" also renders "PT0S").
|
|
9
9
|
* - Returns "" when `value` is not a valid ISO 8601 duration string.
|
|
@@ -5,7 +5,7 @@ import { isValidDuration } from "../validate/isValidDuration.js";
|
|
|
5
5
|
*
|
|
6
6
|
* - Uses Temporal.Duration.from and .negated, then .toString() to re-emit.
|
|
7
7
|
* - Negating is a pure sign flip on every component, so it never needs `relativeTo` —
|
|
8
|
-
* calendar-unit durations round-trip through it fine, unlike `addDuration`/`
|
|
8
|
+
* calendar-unit durations round-trip through it fine, unlike `addDuration`/`totalDuration`.
|
|
9
9
|
* - A zero-length duration has no sign to flip and comes back as "PT0S", the canonical
|
|
10
10
|
* spelling Temporal emits for every zero duration (so "P0D" also renders "PT0S").
|
|
11
11
|
* - Returns "" when `value` is not a valid ISO 8601 duration string.
|
|
@@ -4,14 +4,20 @@ import type { DateTimeDurationUnit, DurationRelativeTo } from "../../types/index
|
|
|
4
4
|
* Express an ISO 8601 duration as a single fractional total in one unit.
|
|
5
5
|
*
|
|
6
6
|
* - Uses Temporal.Duration.from and .total — the whole duration is converted, so
|
|
7
|
-
*
|
|
8
|
-
* -
|
|
9
|
-
*
|
|
7
|
+
* totalDuration("P1DT2H30M", "hours") is 26.5, not the 2 that `getDurationUnit` reads.
|
|
8
|
+
* - Which function to use: `totalDuration` takes an ISO 8601 duration string. `totalUnits` takes
|
|
9
|
+
* a unit object of exact units, such as `{ minutes: 15 }`. `durationFromUnits` turns a unit
|
|
10
|
+
* object into the duration string this function takes. To total a calendar amount written as a
|
|
11
|
+
* unit object, such as `{ months: 1 }`, pass the result of `durationFromUnits` here with
|
|
12
|
+
* `relativeTo`.
|
|
13
|
+
* - The result is fractional, not rounded: totalDuration("P1DT2H30M", "days") is
|
|
14
|
+
* 1.1041666666666667. Round it yourself, or reach for `normalizeDuration` instead. It is a
|
|
15
|
+
* JavaScript number, so a total past 2^53 is the nearest double.
|
|
10
16
|
* - The calendar-unit rule of `relativeTo` is the same one `normalizeDuration` (A3) carries;
|
|
11
17
|
* `addDuration`/`subtractDuration` (A2) have it worse still, since Temporal gives them no
|
|
12
18
|
* `relativeTo` option at all.
|
|
13
19
|
* - The requested-unit half of that rule bites even on day/time-only input: "P1DT2H30M" has
|
|
14
|
-
* no calendar component, yet
|
|
20
|
+
* no calendar component, yet totalDuration("P1DT2H30M", "weeks") is still null — a week is a
|
|
15
21
|
* calendar quantity to Temporal regardless of what it is being measured from.
|
|
16
22
|
* - A zoned `relativeTo` string resolves its wall time with disambiguation "compatible" and
|
|
17
23
|
* offset "reject", as Temporal does: an ambiguous wall time takes the earlier instant, a
|
|
@@ -38,22 +44,22 @@ import type { DateTimeDurationUnit, DurationRelativeTo } from "../../types/index
|
|
|
38
44
|
* @param options The anchor calendar units are measured from
|
|
39
45
|
* @returns the fractional total in `unit`, or null on invalid input
|
|
40
46
|
*
|
|
41
|
-
* @example
|
|
42
|
-
* @example
|
|
43
|
-
* @example
|
|
44
|
-
* @example
|
|
45
|
-
* @example
|
|
46
|
-
* @example
|
|
47
|
-
* @example
|
|
48
|
-
* @example
|
|
49
|
-
* @example
|
|
50
|
-
* @example
|
|
51
|
-
* @example
|
|
52
|
-
* @example
|
|
53
|
-
* @example
|
|
54
|
-
* @example
|
|
47
|
+
* @example totalDuration("P1DT2H30M", "hours") // 26.5
|
|
48
|
+
* @example totalDuration("P1DT2H30M", "minutes") // 1590
|
|
49
|
+
* @example totalDuration("PT36H", "days") // 1.5
|
|
50
|
+
* @example totalDuration("-PT90M", "hours") // -1.5
|
|
51
|
+
* @example totalDuration("P1M", "days") // null (calendar unit needs relativeTo)
|
|
52
|
+
* @example totalDuration("P1M", "days", { relativeTo: "2024-02-01" }) // 29
|
|
53
|
+
* @example totalDuration("P1M", "days", { relativeTo: "20240201" }) // null (basic format)
|
|
54
|
+
* @example totalDuration("P1D", "hours", { relativeTo: "2024-03-10T00:00:00-05:00[America/New_York]" }) // 23 (spring-forward)
|
|
55
|
+
* @example totalDuration("P1D", "hours", { relativeTo: "2024-11-03T01:30[America/New_York]" }) // 25
|
|
56
|
+
* @example totalDuration("P1DT2H30M", "minute") // 1590 (singular unit name)
|
|
57
|
+
* @example totalDuration("not a duration", "hours") // null
|
|
58
|
+
* @example totalDuration("P1Y", "days", { relativeTo: "2024-02-24[u-ca=hebrew]" }) // 385 (Hebrew leap year 5784)
|
|
59
|
+
* @example totalDuration("P1M", "days", { relativeTo: "2024-02-10[!u-ca=hebrew]" }) // 30 (1 Adar I 5784; the critical flag is accepted)
|
|
60
|
+
* @example totalDuration("P1M", "days", { relativeTo: "2024-02-10T00:00:00[u-ca=hebrew]" }) // 30 (a date-time without a zone reads as its date, as Temporal reads relativeTo)
|
|
55
61
|
*/
|
|
56
|
-
export declare function
|
|
62
|
+
export declare function totalDuration(value: string, unit: DateTimeDurationUnit | Temporal.DateTimeUnit, options?: {
|
|
57
63
|
/**
|
|
58
64
|
* The date or zoned date-time the duration is measured from. It is required whenever a year,
|
|
59
65
|
* month or week is involved, as the `unit` asked for or as a nonzero field of the duration.
|
|
@@ -8,14 +8,20 @@ import { isOptionsArgument } from "../../internal/isObject.js";
|
|
|
8
8
|
* Express an ISO 8601 duration as a single fractional total in one unit.
|
|
9
9
|
*
|
|
10
10
|
* - Uses Temporal.Duration.from and .total — the whole duration is converted, so
|
|
11
|
-
*
|
|
12
|
-
* -
|
|
13
|
-
*
|
|
11
|
+
* totalDuration("P1DT2H30M", "hours") is 26.5, not the 2 that `getDurationUnit` reads.
|
|
12
|
+
* - Which function to use: `totalDuration` takes an ISO 8601 duration string. `totalUnits` takes
|
|
13
|
+
* a unit object of exact units, such as `{ minutes: 15 }`. `durationFromUnits` turns a unit
|
|
14
|
+
* object into the duration string this function takes. To total a calendar amount written as a
|
|
15
|
+
* unit object, such as `{ months: 1 }`, pass the result of `durationFromUnits` here with
|
|
16
|
+
* `relativeTo`.
|
|
17
|
+
* - The result is fractional, not rounded: totalDuration("P1DT2H30M", "days") is
|
|
18
|
+
* 1.1041666666666667. Round it yourself, or reach for `normalizeDuration` instead. It is a
|
|
19
|
+
* JavaScript number, so a total past 2^53 is the nearest double.
|
|
14
20
|
* - The calendar-unit rule of `relativeTo` is the same one `normalizeDuration` (A3) carries;
|
|
15
21
|
* `addDuration`/`subtractDuration` (A2) have it worse still, since Temporal gives them no
|
|
16
22
|
* `relativeTo` option at all.
|
|
17
23
|
* - The requested-unit half of that rule bites even on day/time-only input: "P1DT2H30M" has
|
|
18
|
-
* no calendar component, yet
|
|
24
|
+
* no calendar component, yet totalDuration("P1DT2H30M", "weeks") is still null — a week is a
|
|
19
25
|
* calendar quantity to Temporal regardless of what it is being measured from.
|
|
20
26
|
* - A zoned `relativeTo` string resolves its wall time with disambiguation "compatible" and
|
|
21
27
|
* offset "reject", as Temporal does: an ambiguous wall time takes the earlier instant, a
|
|
@@ -42,22 +48,22 @@ import { isOptionsArgument } from "../../internal/isObject.js";
|
|
|
42
48
|
* @param options The anchor calendar units are measured from
|
|
43
49
|
* @returns the fractional total in `unit`, or null on invalid input
|
|
44
50
|
*
|
|
45
|
-
* @example
|
|
46
|
-
* @example
|
|
47
|
-
* @example
|
|
48
|
-
* @example
|
|
49
|
-
* @example
|
|
50
|
-
* @example
|
|
51
|
-
* @example
|
|
52
|
-
* @example
|
|
53
|
-
* @example
|
|
54
|
-
* @example
|
|
55
|
-
* @example
|
|
56
|
-
* @example
|
|
57
|
-
* @example
|
|
58
|
-
* @example
|
|
51
|
+
* @example totalDuration("P1DT2H30M", "hours") // 26.5
|
|
52
|
+
* @example totalDuration("P1DT2H30M", "minutes") // 1590
|
|
53
|
+
* @example totalDuration("PT36H", "days") // 1.5
|
|
54
|
+
* @example totalDuration("-PT90M", "hours") // -1.5
|
|
55
|
+
* @example totalDuration("P1M", "days") // null (calendar unit needs relativeTo)
|
|
56
|
+
* @example totalDuration("P1M", "days", { relativeTo: "2024-02-01" }) // 29
|
|
57
|
+
* @example totalDuration("P1M", "days", { relativeTo: "20240201" }) // null (basic format)
|
|
58
|
+
* @example totalDuration("P1D", "hours", { relativeTo: "2024-03-10T00:00:00-05:00[America/New_York]" }) // 23 (spring-forward)
|
|
59
|
+
* @example totalDuration("P1D", "hours", { relativeTo: "2024-11-03T01:30[America/New_York]" }) // 25
|
|
60
|
+
* @example totalDuration("P1DT2H30M", "minute") // 1590 (singular unit name)
|
|
61
|
+
* @example totalDuration("not a duration", "hours") // null
|
|
62
|
+
* @example totalDuration("P1Y", "days", { relativeTo: "2024-02-24[u-ca=hebrew]" }) // 385 (Hebrew leap year 5784)
|
|
63
|
+
* @example totalDuration("P1M", "days", { relativeTo: "2024-02-10[!u-ca=hebrew]" }) // 30 (1 Adar I 5784; the critical flag is accepted)
|
|
64
|
+
* @example totalDuration("P1M", "days", { relativeTo: "2024-02-10T00:00:00[u-ca=hebrew]" }) // 30 (a date-time without a zone reads as its date, as Temporal reads relativeTo)
|
|
59
65
|
*/
|
|
60
|
-
export function
|
|
66
|
+
export function totalDuration(value, unit, options) {
|
|
61
67
|
if (!isOptionsArgument(options)) {
|
|
62
68
|
return null;
|
|
63
69
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { ExactDurationUnit, TimeUnit } from "../../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Express an amount written as a unit object, such as `{ minutes: 15 }`, as a single fractional
|
|
4
|
+
* total in one unit.
|
|
5
|
+
*
|
|
6
|
+
* - Uses Temporal.Duration.from and .total: every field is converted, so
|
|
7
|
+
* totalUnits({ days: 1, hours: 12 }, "seconds") is 129600.
|
|
8
|
+
* - Which function to use: `totalUnits` takes a unit object. `totalDuration` takes an ISO 8601
|
|
9
|
+
* duration string (`"PT15M"`). `durationFromUnits` turns a unit object into the duration string
|
|
10
|
+
* that the other duration functions take.
|
|
11
|
+
* - Takes exact units only: days, hours, minutes, seconds, milliseconds, microseconds and
|
|
12
|
+
* nanoseconds. A day is 24 hours, as Temporal's `Duration.prototype.total` reads a day when it
|
|
13
|
+
* has no `relativeTo`. For a day in a time zone, which can be 23 or 25 hours across a clock
|
|
14
|
+
* change, use `totalDuration` with a zoned `relativeTo`.
|
|
15
|
+
* - A year, a month or a week returns null, as a key and as `unit`: Temporal gives them no length
|
|
16
|
+
* without a date to measure from. Write a week as `{ days: 7 }`. For a calendar amount, build
|
|
17
|
+
* the string with `durationFromUnits` and pass it to `totalDuration` with `relativeTo`.
|
|
18
|
+
* - The result is fractional, not rounded: totalUnits({ hours: 36 }, "days") is 1.5. It is a
|
|
19
|
+
* JavaScript number, so a total past 2^53 is the nearest double.
|
|
20
|
+
* - Every key is a unit name in the plural, and every amount is a whole finite number. All
|
|
21
|
+
* nonzero amounts share one sign, as Temporal requires of a duration. A unit set to `undefined`
|
|
22
|
+
* is absent, as Temporal reads it.
|
|
23
|
+
* - An unknown key returns null, even beside a valid one. Temporal on its own ignores an unknown
|
|
24
|
+
* key, so a misspelt `{ minutes: 15, hour: 1 }` would total 900 with no warning.
|
|
25
|
+
* - `unit` accepts the plural or singular name (`"seconds"` or `"second"`), as Temporal does.
|
|
26
|
+
* - Returns null on an object with no unit, a non-object `units` (a duration string included), an
|
|
27
|
+
* invalid amount, an amount past Temporal's duration range, or an invalid `unit`.
|
|
28
|
+
*
|
|
29
|
+
* @param units Partial<Record<ExactDurationUnit, number>> object holding the amount to total
|
|
30
|
+
* @param unit ExactDurationUnit to total into ("days" | "hours" | "minutes" | "seconds" | "milliseconds" | "microseconds" | "nanoseconds", or the singular name)
|
|
31
|
+
* @returns the fractional total in `unit`, or null on invalid input
|
|
32
|
+
*
|
|
33
|
+
* @example totalUnits({ minutes: 15 }, "seconds") // 900
|
|
34
|
+
* @example totalUnits({ days: 30 }, "seconds") // 2592000
|
|
35
|
+
* @example totalUnits({ days: 1, hours: 12 }, "seconds") // 129600
|
|
36
|
+
* @example totalUnits({ hours: 36 }, "days") // 1.5
|
|
37
|
+
* @example totalUnits({ minutes: -90 }, "hours") // -1.5
|
|
38
|
+
* @example totalUnits({ seconds: 10 }, "millisecond") // 10000 (singular unit name)
|
|
39
|
+
* @example totalUnits({ minutes: 0 }, "seconds") // 0
|
|
40
|
+
* @example totalUnits({ minutes: 15, hours: undefined }, "seconds") // 900 (an undefined unit is absent)
|
|
41
|
+
* @example totalUnits({ weeks: 1 }, "days") // null (a week has no exact length; write { days: 7 })
|
|
42
|
+
* @example totalUnits({ days: 7 }, "weeks") // null (a week has no exact length)
|
|
43
|
+
* @example totalUnits({ minutes: 15, hour: 1 }, "seconds") // null (unknown key "hour")
|
|
44
|
+
* @example totalUnits({ minutes: 1.5 }, "seconds") // null (fractional amount)
|
|
45
|
+
* @example totalUnits({ hours: 1, minutes: -30 }, "seconds") // null (mixed signs)
|
|
46
|
+
* @example totalUnits({}, "seconds") // null
|
|
47
|
+
* @example totalUnits("PT15M", "seconds") // null (a duration string goes to totalDuration)
|
|
48
|
+
*/
|
|
49
|
+
export declare function totalUnits(units: Partial<Record<ExactDurationUnit, number>>, unit: ExactDurationUnit | "day" | TimeUnit): number | null;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
2
|
+
import { durationTotal, readDurationUnits } from "../../internal/index.js";
|
|
3
|
+
import { resolveDurationUnit } from "../../internal/resolveDurationUnit.js";
|
|
4
|
+
import { isValidTimeDurationUnit } from "../../plain/validate/index.js";
|
|
5
|
+
/** Whether `unit` has an exact length: `"days"` (24 hours with no anchor) or a time unit. */
|
|
6
|
+
const isExactDurationUnit = (unit) => unit === "days" || isValidTimeDurationUnit(unit);
|
|
7
|
+
/**
|
|
8
|
+
* Express an amount written as a unit object, such as `{ minutes: 15 }`, as a single fractional
|
|
9
|
+
* total in one unit.
|
|
10
|
+
*
|
|
11
|
+
* - Uses Temporal.Duration.from and .total: every field is converted, so
|
|
12
|
+
* totalUnits({ days: 1, hours: 12 }, "seconds") is 129600.
|
|
13
|
+
* - Which function to use: `totalUnits` takes a unit object. `totalDuration` takes an ISO 8601
|
|
14
|
+
* duration string (`"PT15M"`). `durationFromUnits` turns a unit object into the duration string
|
|
15
|
+
* that the other duration functions take.
|
|
16
|
+
* - Takes exact units only: days, hours, minutes, seconds, milliseconds, microseconds and
|
|
17
|
+
* nanoseconds. A day is 24 hours, as Temporal's `Duration.prototype.total` reads a day when it
|
|
18
|
+
* has no `relativeTo`. For a day in a time zone, which can be 23 or 25 hours across a clock
|
|
19
|
+
* change, use `totalDuration` with a zoned `relativeTo`.
|
|
20
|
+
* - A year, a month or a week returns null, as a key and as `unit`: Temporal gives them no length
|
|
21
|
+
* without a date to measure from. Write a week as `{ days: 7 }`. For a calendar amount, build
|
|
22
|
+
* the string with `durationFromUnits` and pass it to `totalDuration` with `relativeTo`.
|
|
23
|
+
* - The result is fractional, not rounded: totalUnits({ hours: 36 }, "days") is 1.5. It is a
|
|
24
|
+
* JavaScript number, so a total past 2^53 is the nearest double.
|
|
25
|
+
* - Every key is a unit name in the plural, and every amount is a whole finite number. All
|
|
26
|
+
* nonzero amounts share one sign, as Temporal requires of a duration. A unit set to `undefined`
|
|
27
|
+
* is absent, as Temporal reads it.
|
|
28
|
+
* - An unknown key returns null, even beside a valid one. Temporal on its own ignores an unknown
|
|
29
|
+
* key, so a misspelt `{ minutes: 15, hour: 1 }` would total 900 with no warning.
|
|
30
|
+
* - `unit` accepts the plural or singular name (`"seconds"` or `"second"`), as Temporal does.
|
|
31
|
+
* - Returns null on an object with no unit, a non-object `units` (a duration string included), an
|
|
32
|
+
* invalid amount, an amount past Temporal's duration range, or an invalid `unit`.
|
|
33
|
+
*
|
|
34
|
+
* @param units Partial<Record<ExactDurationUnit, number>> object holding the amount to total
|
|
35
|
+
* @param unit ExactDurationUnit to total into ("days" | "hours" | "minutes" | "seconds" | "milliseconds" | "microseconds" | "nanoseconds", or the singular name)
|
|
36
|
+
* @returns the fractional total in `unit`, or null on invalid input
|
|
37
|
+
*
|
|
38
|
+
* @example totalUnits({ minutes: 15 }, "seconds") // 900
|
|
39
|
+
* @example totalUnits({ days: 30 }, "seconds") // 2592000
|
|
40
|
+
* @example totalUnits({ days: 1, hours: 12 }, "seconds") // 129600
|
|
41
|
+
* @example totalUnits({ hours: 36 }, "days") // 1.5
|
|
42
|
+
* @example totalUnits({ minutes: -90 }, "hours") // -1.5
|
|
43
|
+
* @example totalUnits({ seconds: 10 }, "millisecond") // 10000 (singular unit name)
|
|
44
|
+
* @example totalUnits({ minutes: 0 }, "seconds") // 0
|
|
45
|
+
* @example totalUnits({ minutes: 15, hours: undefined }, "seconds") // 900 (an undefined unit is absent)
|
|
46
|
+
* @example totalUnits({ weeks: 1 }, "days") // null (a week has no exact length; write { days: 7 })
|
|
47
|
+
* @example totalUnits({ days: 7 }, "weeks") // null (a week has no exact length)
|
|
48
|
+
* @example totalUnits({ minutes: 15, hour: 1 }, "seconds") // null (unknown key "hour")
|
|
49
|
+
* @example totalUnits({ minutes: 1.5 }, "seconds") // null (fractional amount)
|
|
50
|
+
* @example totalUnits({ hours: 1, minutes: -30 }, "seconds") // null (mixed signs)
|
|
51
|
+
* @example totalUnits({}, "seconds") // null
|
|
52
|
+
* @example totalUnits("PT15M", "seconds") // null (a duration string goes to totalDuration)
|
|
53
|
+
*/
|
|
54
|
+
export function totalUnits(units, unit) {
|
|
55
|
+
try {
|
|
56
|
+
const resolvedUnit = resolveDurationUnit(unit);
|
|
57
|
+
const amounts = readDurationUnits(units, isExactDurationUnit);
|
|
58
|
+
if (!isExactDurationUnit(resolvedUnit) || amounts === null) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
return durationTotal(Temporal.Duration.from(amounts), resolvedUnit);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// Never throws (Core Rule 3): a hostile
|
|
70
|
+
// argument is invalid input, not an exception.
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -9,7 +9,7 @@ import type { DurationRelativeTo } from "../../types/index.js";
|
|
|
9
9
|
* Temporal checks identity first. Note the asymmetry with `addDuration`/`subtractDuration`
|
|
10
10
|
* (A2): Temporal.Duration.compare *does* accept `relativeTo`, while .add/.subtract do not,
|
|
11
11
|
* so calendar-unit durations are comparable here even though they cannot be combined there.
|
|
12
|
-
* `
|
|
12
|
+
* `totalDuration` and `normalizeDuration` (A3) carry the same relativeTo rule as this function.
|
|
13
13
|
* - The anchor genuinely decides the answer rather than merely unblocking it: "P1M" is longer
|
|
14
14
|
* than "P30D" relative to January (31 days) and shorter relative to February 2024 (29).
|
|
15
15
|
* - A zoned `relativeTo` string resolves its wall time with disambiguation "compatible" and
|
|
@@ -11,7 +11,7 @@ import { isOptionsArgument } from "../../internal/isObject.js";
|
|
|
11
11
|
* Temporal checks identity first. Note the asymmetry with `addDuration`/`subtractDuration`
|
|
12
12
|
* (A2): Temporal.Duration.compare *does* accept `relativeTo`, while .add/.subtract do not,
|
|
13
13
|
* so calendar-unit durations are comparable here even though they cannot be combined there.
|
|
14
|
-
* `
|
|
14
|
+
* `totalDuration` and `normalizeDuration` (A3) carry the same relativeTo rule as this function.
|
|
15
15
|
* - The anchor genuinely decides the answer rather than merely unblocking it: "P1M" is longer
|
|
16
16
|
* than "P30D" relative to January (31 days) and shorter relative to February 2024 (29).
|
|
17
17
|
* - A zoned `relativeTo` string resolves its wall time with disambiguation "compatible" and
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { DutyDay, Interval } from "../../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Return the operator-designated day an instant falls in: from the most recent `dayStartTime`
|
|
4
|
+
* in `timeZone` at or before the instant, up to (not including) the next one.
|
|
5
|
+
*
|
|
6
|
+
* The day an hours-of-work rule counts is the operator's, not the local midnight where the
|
|
7
|
+
* person happens to be, so the reference zone and the start time are both the caller's and
|
|
8
|
+
* neither has a default.
|
|
9
|
+
*
|
|
10
|
+
* - A `dayStartTime` that a clock change skips or repeats is resolved under `day.disambiguation`,
|
|
11
|
+
* the CORE-4 policy in `resolveLocal`. The default, `"compatible"`, reads a skipped time after
|
|
12
|
+
* the gap (02:30 on New York's spring-forward day is 03:30) and a repeated one at its first
|
|
13
|
+
* pass. The day that holds the change is then shorter or longer by the change: 23 or 25 hours
|
|
14
|
+
* across a one-hour change, 24.5 across Lord Howe's 30-minute fall-back, 21 across Casey's
|
|
15
|
+
* three-hour jump. `"reject"` returns `null` for
|
|
16
|
+
* a day that starts or ends at such a time.
|
|
17
|
+
* - The instant is read in `timeZone` whatever offset or zone it is written with, so a log whose
|
|
18
|
+
* entries cross zones still falls into the reference zone's days.
|
|
19
|
+
* - A date whose start resolves onto the next date's start opens no day: the date
|
|
20
|
+
* `Pacific/Apia` deleted in 2011 is part of no operator day.
|
|
21
|
+
* - Returns `null` when `instant` is not an ISO 8601 instant string, when `day` is not an object
|
|
22
|
+
* with a valid `timeZone` and a `dayStartTime` that `isValidTime` accepts, and when the day or
|
|
23
|
+
* the next one starts outside Temporal's instant range.
|
|
24
|
+
*
|
|
25
|
+
* @param instant ISO 8601 instant string to place
|
|
26
|
+
* @param day the reference zone and the local time each day starts at
|
|
27
|
+
* @returns `{ start, end }` of the day as UTC instants ending in "Z", or null on invalid input
|
|
28
|
+
*
|
|
29
|
+
* @example dutyDayFor("2024-01-01T08:59:00Z", { timeZone: "America/New_York", dayStartTime: "04:00" }) // { start: "2023-12-31T09:00:00Z", end: "2024-01-01T09:00:00Z" } — 03:59 local is the previous day
|
|
30
|
+
* @example dutyDayFor("2024-01-01T09:00:00Z", { timeZone: "America/New_York", dayStartTime: "04:00" }) // { start: "2024-01-01T09:00:00Z", end: "2024-01-02T09:00:00Z" }
|
|
31
|
+
* @example dutyDayFor("2024-03-10T12:00:00Z", { timeZone: "America/New_York", dayStartTime: "02:30" }) // { start: "2024-03-10T07:30:00Z", end: "2024-03-11T06:30:00Z" } — 02:30 is skipped, read as 03:30; 23 hours
|
|
32
|
+
* @example dutyDayFor("2024-11-03T12:00:00Z", { timeZone: "America/New_York", dayStartTime: "01:30" }) // { start: "2024-11-03T05:30:00Z", end: "2024-11-04T06:30:00Z" } — 01:30 is repeated, the first pass starts it; 25 hours
|
|
33
|
+
* @example dutyDayFor("2024-11-03T12:00:00Z", { timeZone: "America/New_York", dayStartTime: "01:30", disambiguation: "later" }) // { start: "2024-11-03T06:30:00Z", end: "2024-11-04T06:30:00Z" } — the second pass; 24 hours
|
|
34
|
+
* @example dutyDayFor("2024-11-03T12:00:00Z", { timeZone: "America/New_York", dayStartTime: "01:30", disambiguation: "reject" }) // null — the day starts at a repeated time
|
|
35
|
+
* @example dutyDayFor("2024-01-01T12:00:00Z", { timeZone: "UTC" }) // null — no dayStartTime
|
|
36
|
+
* @example dutyDayFor("2024-01-01T12:00:00Z", { timeZone: "Invalid/Zone", dayStartTime: "04:00" }) // null
|
|
37
|
+
*/
|
|
38
|
+
export declare function dutyDayFor(instant: string, day: DutyDay): Interval | null;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
2
|
+
import { isObject, parseInstantNanoseconds, zoneFrame } from "../../internal/index.js";
|
|
3
|
+
import { operatorDayScale, parseDayStartTime, } from "../../internal/dutyPeriods.js";
|
|
4
|
+
import { parseScheduleDisambiguation } from "../../internal/operatingSchedule.js";
|
|
5
|
+
/**
|
|
6
|
+
* Return the operator-designated day an instant falls in: from the most recent `dayStartTime`
|
|
7
|
+
* in `timeZone` at or before the instant, up to (not including) the next one.
|
|
8
|
+
*
|
|
9
|
+
* The day an hours-of-work rule counts is the operator's, not the local midnight where the
|
|
10
|
+
* person happens to be, so the reference zone and the start time are both the caller's and
|
|
11
|
+
* neither has a default.
|
|
12
|
+
*
|
|
13
|
+
* - A `dayStartTime` that a clock change skips or repeats is resolved under `day.disambiguation`,
|
|
14
|
+
* the CORE-4 policy in `resolveLocal`. The default, `"compatible"`, reads a skipped time after
|
|
15
|
+
* the gap (02:30 on New York's spring-forward day is 03:30) and a repeated one at its first
|
|
16
|
+
* pass. The day that holds the change is then shorter or longer by the change: 23 or 25 hours
|
|
17
|
+
* across a one-hour change, 24.5 across Lord Howe's 30-minute fall-back, 21 across Casey's
|
|
18
|
+
* three-hour jump. `"reject"` returns `null` for
|
|
19
|
+
* a day that starts or ends at such a time.
|
|
20
|
+
* - The instant is read in `timeZone` whatever offset or zone it is written with, so a log whose
|
|
21
|
+
* entries cross zones still falls into the reference zone's days.
|
|
22
|
+
* - A date whose start resolves onto the next date's start opens no day: the date
|
|
23
|
+
* `Pacific/Apia` deleted in 2011 is part of no operator day.
|
|
24
|
+
* - Returns `null` when `instant` is not an ISO 8601 instant string, when `day` is not an object
|
|
25
|
+
* with a valid `timeZone` and a `dayStartTime` that `isValidTime` accepts, and when the day or
|
|
26
|
+
* the next one starts outside Temporal's instant range.
|
|
27
|
+
*
|
|
28
|
+
* @param instant ISO 8601 instant string to place
|
|
29
|
+
* @param day the reference zone and the local time each day starts at
|
|
30
|
+
* @returns `{ start, end }` of the day as UTC instants ending in "Z", or null on invalid input
|
|
31
|
+
*
|
|
32
|
+
* @example dutyDayFor("2024-01-01T08:59:00Z", { timeZone: "America/New_York", dayStartTime: "04:00" }) // { start: "2023-12-31T09:00:00Z", end: "2024-01-01T09:00:00Z" } — 03:59 local is the previous day
|
|
33
|
+
* @example dutyDayFor("2024-01-01T09:00:00Z", { timeZone: "America/New_York", dayStartTime: "04:00" }) // { start: "2024-01-01T09:00:00Z", end: "2024-01-02T09:00:00Z" }
|
|
34
|
+
* @example dutyDayFor("2024-03-10T12:00:00Z", { timeZone: "America/New_York", dayStartTime: "02:30" }) // { start: "2024-03-10T07:30:00Z", end: "2024-03-11T06:30:00Z" } — 02:30 is skipped, read as 03:30; 23 hours
|
|
35
|
+
* @example dutyDayFor("2024-11-03T12:00:00Z", { timeZone: "America/New_York", dayStartTime: "01:30" }) // { start: "2024-11-03T05:30:00Z", end: "2024-11-04T06:30:00Z" } — 01:30 is repeated, the first pass starts it; 25 hours
|
|
36
|
+
* @example dutyDayFor("2024-11-03T12:00:00Z", { timeZone: "America/New_York", dayStartTime: "01:30", disambiguation: "later" }) // { start: "2024-11-03T06:30:00Z", end: "2024-11-04T06:30:00Z" } — the second pass; 24 hours
|
|
37
|
+
* @example dutyDayFor("2024-11-03T12:00:00Z", { timeZone: "America/New_York", dayStartTime: "01:30", disambiguation: "reject" }) // null — the day starts at a repeated time
|
|
38
|
+
* @example dutyDayFor("2024-01-01T12:00:00Z", { timeZone: "UTC" }) // null — no dayStartTime
|
|
39
|
+
* @example dutyDayFor("2024-01-01T12:00:00Z", { timeZone: "Invalid/Zone", dayStartTime: "04:00" }) // null
|
|
40
|
+
*/
|
|
41
|
+
export function dutyDayFor(instant, day) {
|
|
42
|
+
try {
|
|
43
|
+
if (typeof instant !== "string" || !isObject(day)) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const { timeZone, dayStartTime } = day;
|
|
47
|
+
const disambiguation = parseScheduleDisambiguation(day);
|
|
48
|
+
const at = parseInstantNanoseconds(instant);
|
|
49
|
+
const frame = zoneFrame(timeZone);
|
|
50
|
+
const time = parseDayStartTime(dayStartTime);
|
|
51
|
+
if (at === null ||
|
|
52
|
+
frame === null ||
|
|
53
|
+
time === null ||
|
|
54
|
+
disambiguation === null) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
const span = operatorDayScale(frame, time, disambiguation).containing(at);
|
|
58
|
+
if (span === null) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
start: Temporal.Instant.fromEpochNanoseconds(span.start).toString(),
|
|
63
|
+
end: Temporal.Instant.fromEpochNanoseconds(span.end).toString(),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// Never throws (Core Rule 3): a hostile
|
|
68
|
+
// argument is invalid input, not an exception.
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { DutyEntry, Interval } from "../../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Return the time a duty log spends in any of `statuses` inside a window, as an exact ISO 8601
|
|
4
|
+
* duration.
|
|
5
|
+
*
|
|
6
|
+
* - The interval algebra of CORE-6: the entries in `statuses` are merged, each run is cut to
|
|
7
|
+
* `window` (half-open), and what is left is summed. An entry that crosses the window's edge
|
|
8
|
+
* counts only its part inside.
|
|
9
|
+
* - Hours are the largest unit, as `sumIntervals` writes it: `"PT49H30M"`, never days.
|
|
10
|
+
* - `[]` as `statuses`, an empty log or an empty window gives `"PT0S"`.
|
|
11
|
+
* - Returns `""` when the log fails `isValidDutyLog`, when `window` is not a valid `Interval`, and
|
|
12
|
+
* when `statuses` is not an array of strings.
|
|
13
|
+
*
|
|
14
|
+
* @param log the duty log, ordered and non-overlapping
|
|
15
|
+
* @param window `{ start, end }` record of ISO 8601 instant strings to total inside
|
|
16
|
+
* @param statuses the statuses whose time is totalled
|
|
17
|
+
* @returns ISO 8601 duration string, or "" on invalid input
|
|
18
|
+
*
|
|
19
|
+
* @example dutyTotals([{ status: "driving", start: "2024-01-01T10:00:00Z", end: "2024-01-01T15:00:00Z" }, { status: "onDuty", start: "2024-01-01T15:00:00Z", end: "2024-01-01T17:00:00Z" }, { status: "driving", start: "2024-01-01T17:00:00Z", end: "2024-01-01T20:00:00Z" }], { start: "2024-01-01T00:00:00Z", end: "2024-01-02T00:00:00Z" }, ["driving"]) // "PT8H"
|
|
20
|
+
* @example dutyTotals([{ status: "driving", start: "2024-01-01T10:00:00Z", end: "2024-01-01T15:00:00Z" }], { start: "2024-01-01T12:00:00Z", end: "2024-01-01T18:00:00Z" }, ["driving"]) // "PT3H" — cut at the window
|
|
21
|
+
* @example dutyTotals([], { start: "2024-01-01T00:00:00Z", end: "2024-01-02T00:00:00Z" }, ["driving"]) // "PT0S"
|
|
22
|
+
* @example dutyTotals([{ status: "driving", start: "2024-01-01T15:00:00Z", end: "2024-01-01T10:00:00Z" }], { start: "2024-01-01T00:00:00Z", end: "2024-01-02T00:00:00Z" }, ["driving"]) // "" — inverted entry
|
|
23
|
+
*/
|
|
24
|
+
export declare function dutyTotals(log: DutyEntry[], window: Interval, statuses: string[]): string;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { formatHourDuration, parseIntervalNanoseconds } from "../../internal/index.js";
|
|
2
|
+
import { parseDutyLog } from "../../internal/dutyLog.js";
|
|
3
|
+
import { readStatusList, timeIn } from "../../internal/dutyEngine.js";
|
|
4
|
+
/**
|
|
5
|
+
* Return the time a duty log spends in any of `statuses` inside a window, as an exact ISO 8601
|
|
6
|
+
* duration.
|
|
7
|
+
*
|
|
8
|
+
* - The interval algebra of CORE-6: the entries in `statuses` are merged, each run is cut to
|
|
9
|
+
* `window` (half-open), and what is left is summed. An entry that crosses the window's edge
|
|
10
|
+
* counts only its part inside.
|
|
11
|
+
* - Hours are the largest unit, as `sumIntervals` writes it: `"PT49H30M"`, never days.
|
|
12
|
+
* - `[]` as `statuses`, an empty log or an empty window gives `"PT0S"`.
|
|
13
|
+
* - Returns `""` when the log fails `isValidDutyLog`, when `window` is not a valid `Interval`, and
|
|
14
|
+
* when `statuses` is not an array of strings.
|
|
15
|
+
*
|
|
16
|
+
* @param log the duty log, ordered and non-overlapping
|
|
17
|
+
* @param window `{ start, end }` record of ISO 8601 instant strings to total inside
|
|
18
|
+
* @param statuses the statuses whose time is totalled
|
|
19
|
+
* @returns ISO 8601 duration string, or "" on invalid input
|
|
20
|
+
*
|
|
21
|
+
* @example dutyTotals([{ status: "driving", start: "2024-01-01T10:00:00Z", end: "2024-01-01T15:00:00Z" }, { status: "onDuty", start: "2024-01-01T15:00:00Z", end: "2024-01-01T17:00:00Z" }, { status: "driving", start: "2024-01-01T17:00:00Z", end: "2024-01-01T20:00:00Z" }], { start: "2024-01-01T00:00:00Z", end: "2024-01-02T00:00:00Z" }, ["driving"]) // "PT8H"
|
|
22
|
+
* @example dutyTotals([{ status: "driving", start: "2024-01-01T10:00:00Z", end: "2024-01-01T15:00:00Z" }], { start: "2024-01-01T12:00:00Z", end: "2024-01-01T18:00:00Z" }, ["driving"]) // "PT3H" — cut at the window
|
|
23
|
+
* @example dutyTotals([], { start: "2024-01-01T00:00:00Z", end: "2024-01-02T00:00:00Z" }, ["driving"]) // "PT0S"
|
|
24
|
+
* @example dutyTotals([{ status: "driving", start: "2024-01-01T15:00:00Z", end: "2024-01-01T10:00:00Z" }], { start: "2024-01-01T00:00:00Z", end: "2024-01-02T00:00:00Z" }, ["driving"]) // "" — inverted entry
|
|
25
|
+
*/
|
|
26
|
+
export function dutyTotals(log, window, statuses) {
|
|
27
|
+
try {
|
|
28
|
+
const entries = parseDutyLog(log);
|
|
29
|
+
const bounds = parseIntervalNanoseconds(window);
|
|
30
|
+
const counted = readStatusList(statuses);
|
|
31
|
+
if (entries === null || bounds === null || counted === null) {
|
|
32
|
+
return "";
|
|
33
|
+
}
|
|
34
|
+
return formatHourDuration(timeIn(entries, counted, bounds.start, bounds.end));
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Never throws (Core Rule 3): a hostile
|
|
38
|
+
// argument is invalid input, not an exception.
|
|
39
|
+
return "";
|
|
40
|
+
}
|
|
41
|
+
}
|