@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,32 @@
|
|
|
1
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
2
|
+
import { isValidUtc } from "../utc/validate/isValidUtc.js";
|
|
3
|
+
import { frameWallClock, normalizeZoneFrame } from "./zoneFrame.js";
|
|
4
|
+
/**
|
|
5
|
+
* Read a UTC ISO string on a local wall clock for the `parse*FromUtc` accessors: the instant it
|
|
6
|
+
* names, on the wall clock of `options.timeZone`. The utc twin of `unixWallClock`.
|
|
7
|
+
*
|
|
8
|
+
* - `timeZone` defaults to `"UTC"`; `"local"` is the system zone; a time zone identifier or a
|
|
9
|
+
* stored UTC offset (`±HH:MM[:SS]`) is read as written; anything else is invalid (see
|
|
10
|
+
* `normalizeZoneFrame`).
|
|
11
|
+
*
|
|
12
|
+
* @param value UTC ISO 8601 datetime string
|
|
13
|
+
* @param options optional `{ timeZone }`
|
|
14
|
+
* @returns the local wall clock, or null when the value or the zone is invalid
|
|
15
|
+
* @example utcWallClock("2024-03-15T14:30:00Z", { timeZone: "Asia/Tokyo" })?.toString() // "2024-03-15T23:30:00"
|
|
16
|
+
* @example utcWallClock("1970-01-01T12:44:30Z", { timeZone: "-00:44:30" })?.toString() // "1970-01-01T12:00:00"
|
|
17
|
+
* @example utcWallClock("2024-03-15T14:30:00Z", { timeZone: "Invalid/Zone" }) // null
|
|
18
|
+
* @example utcWallClock("2024-03-15T14:30:00") // null (no Z)
|
|
19
|
+
*/
|
|
20
|
+
export function utcWallClock(value, options) {
|
|
21
|
+
if (!isValidUtc(value))
|
|
22
|
+
return null;
|
|
23
|
+
const frame = normalizeZoneFrame(options?.timeZone);
|
|
24
|
+
if (frame === null)
|
|
25
|
+
return null;
|
|
26
|
+
try {
|
|
27
|
+
return frameWallClock(Temporal.Instant.from(value), frame);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve `TwoDigitYearOptions.yearWindow` to the first year of a hundred-year window, or null
|
|
3
|
+
* when the option is absent or not one of its two forms.
|
|
4
|
+
*
|
|
5
|
+
* - An integer from 0 to 9900 is a fixed window starting in that year.
|
|
6
|
+
* - `"rolling"` (exact match) is the hundred years around today: 50 years before the current UTC
|
|
7
|
+
* calendar year to 49 after it. The year is read once, from
|
|
8
|
+
* `Temporal.Now.instant().toZonedDateTimeISO("UTC").year`, so the window moves at the UTC new
|
|
9
|
+
* year, not mid-year: year granularity is a **GMT rule**. RFC 9110 §5.6.7 applies the same
|
|
10
|
+
* 50-year idea to an `rfc850-date` two-digit year, at day granularity; `internal/httpDateFields.ts`
|
|
11
|
+
* implements that rule for HTTP dates and is not affected by this one.
|
|
12
|
+
* - Anything else (a non-integer, a negative, 9901, `NaN`, `Infinity`, a numeric string, any
|
|
13
|
+
* other string, `null`) is null. Whether a null window matters is the caller's: a value with no
|
|
14
|
+
* two-digit year needs none.
|
|
15
|
+
*
|
|
16
|
+
* `options` is read as an Object the way Temporal's GetOptionsObject reads one (a function is an
|
|
17
|
+
* Object); a non-Object yields null here, and the public function has already returned its
|
|
18
|
+
* sentinel for one by `isOptionsArgument`.
|
|
19
|
+
*
|
|
20
|
+
* @param options the caller's options bag
|
|
21
|
+
* @returns the window's first year, or null
|
|
22
|
+
*
|
|
23
|
+
* @example readYearWindowStart({ yearWindow: 1950 }) // 1950
|
|
24
|
+
* @example readYearWindowStart({ yearWindow: "rolling" }) // 1976 (in 2026)
|
|
25
|
+
* @example readYearWindowStart({}) // null
|
|
26
|
+
* @example readYearWindowStart({ yearWindow: 9901 }) // null
|
|
27
|
+
*/
|
|
28
|
+
export declare function readYearWindowStart(options: unknown): number | null;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
2
|
+
import { isObject } from "./isObject.js";
|
|
3
|
+
/** `TwoDigitYearOptions.yearWindow` as a number: the first year of the window, 0–9900. */
|
|
4
|
+
const MIN_YEAR_WINDOW_START = 0;
|
|
5
|
+
/** The highest start whose every year, start + 99, is still a four-digit ISO year. */
|
|
6
|
+
const MAX_YEAR_WINDOW_START = 9900;
|
|
7
|
+
/** A rolling window starts this many years before the current UTC calendar year. */
|
|
8
|
+
const ROLLING_YEARS_BEFORE_NOW = 50;
|
|
9
|
+
/**
|
|
10
|
+
* Resolve `TwoDigitYearOptions.yearWindow` to the first year of a hundred-year window, or null
|
|
11
|
+
* when the option is absent or not one of its two forms.
|
|
12
|
+
*
|
|
13
|
+
* - An integer from 0 to 9900 is a fixed window starting in that year.
|
|
14
|
+
* - `"rolling"` (exact match) is the hundred years around today: 50 years before the current UTC
|
|
15
|
+
* calendar year to 49 after it. The year is read once, from
|
|
16
|
+
* `Temporal.Now.instant().toZonedDateTimeISO("UTC").year`, so the window moves at the UTC new
|
|
17
|
+
* year, not mid-year: year granularity is a **GMT rule**. RFC 9110 §5.6.7 applies the same
|
|
18
|
+
* 50-year idea to an `rfc850-date` two-digit year, at day granularity; `internal/httpDateFields.ts`
|
|
19
|
+
* implements that rule for HTTP dates and is not affected by this one.
|
|
20
|
+
* - Anything else (a non-integer, a negative, 9901, `NaN`, `Infinity`, a numeric string, any
|
|
21
|
+
* other string, `null`) is null. Whether a null window matters is the caller's: a value with no
|
|
22
|
+
* two-digit year needs none.
|
|
23
|
+
*
|
|
24
|
+
* `options` is read as an Object the way Temporal's GetOptionsObject reads one (a function is an
|
|
25
|
+
* Object); a non-Object yields null here, and the public function has already returned its
|
|
26
|
+
* sentinel for one by `isOptionsArgument`.
|
|
27
|
+
*
|
|
28
|
+
* @param options the caller's options bag
|
|
29
|
+
* @returns the window's first year, or null
|
|
30
|
+
*
|
|
31
|
+
* @example readYearWindowStart({ yearWindow: 1950 }) // 1950
|
|
32
|
+
* @example readYearWindowStart({ yearWindow: "rolling" }) // 1976 (in 2026)
|
|
33
|
+
* @example readYearWindowStart({}) // null
|
|
34
|
+
* @example readYearWindowStart({ yearWindow: 9901 }) // null
|
|
35
|
+
*/
|
|
36
|
+
export function readYearWindowStart(options) {
|
|
37
|
+
if (!isObject(options)) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
const { yearWindow } = options;
|
|
41
|
+
if (yearWindow === "rolling") {
|
|
42
|
+
return (Temporal.Now.instant().toZonedDateTimeISO("UTC").year -
|
|
43
|
+
ROLLING_YEARS_BEFORE_NOW);
|
|
44
|
+
}
|
|
45
|
+
if (typeof yearWindow === "number" &&
|
|
46
|
+
Number.isInteger(yearWindow) &&
|
|
47
|
+
yearWindow >= MIN_YEAR_WINDOW_START &&
|
|
48
|
+
yearWindow <= MAX_YEAR_WINDOW_START) {
|
|
49
|
+
return yearWindow;
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
2
|
+
import type { ZoneBucketUnit } from "../types/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* True when `[start, end)` certainly touches more than `max` buckets of `unit`, decided from the span
|
|
5
|
+
* instead of stepping bucket by bucket (which costs milliseconds a step in some zones).
|
|
6
|
+
*
|
|
7
|
+
* Over a prefix of the range, the local wall clock runs continuously between offset transitions.
|
|
8
|
+
* Those stretches cover at least the prefix's length less every backward offset change, in at most
|
|
9
|
+
* one stretch more than there are transitions, and each stretch of wall clock holds at least
|
|
10
|
+
* `floor(length / LONGEST_UNIT_NANOSECONDS)` distinct unit starts, each the start of its own
|
|
11
|
+
* bucket before `end`. The count subtracts two per stretch for the partial units at its ends.
|
|
12
|
+
* The bound also holds for a count of distinct local dates, which the free-time walk keeps by
|
|
13
|
+
* folding a day that re-enters an earlier date: a date can re-enter only at an offset transition,
|
|
14
|
+
* where the two units dropped per stretch already sit, and the starts counted inside one stretch
|
|
15
|
+
* fall on strictly increasing dates.
|
|
16
|
+
* `false` means "not certain": the walk decides, exactly as before.
|
|
17
|
+
*/
|
|
18
|
+
export declare function certainlyTouchesMoreBuckets(startZoned: Temporal.ZonedDateTime, endZoned: Temporal.ZonedDateTime, unit: ZoneBucketUnit, max: number): boolean;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
2
|
+
import { zonedNextTransition } from "./zonedWallClockOperations.js";
|
|
3
|
+
/**
|
|
4
|
+
* A bounded walk over a zone's local buckets (hours, days, weeks, months) can refuse a span that is
|
|
5
|
+
* certainly too long without stepping through it. `bucketRange` refuses a range past 10,000
|
|
6
|
+
* buckets this way, and the free-time walk a dwell past 10,000 local days. `false` always means
|
|
7
|
+
* "not certain": the caller walks, exactly as it would without this check, so no answer changes.
|
|
8
|
+
*/
|
|
9
|
+
const NANOSECONDS_PER_HOUR = 3600000000000n;
|
|
10
|
+
/**
|
|
11
|
+
* The longest wall-clock stretch of each unit. Any wall-clock interval this long holds a unit
|
|
12
|
+
* start: an hour holds an hour start, 24 hours a midnight, 7 days a Monday, 31 days a first of
|
|
13
|
+
* the month.
|
|
14
|
+
*/
|
|
15
|
+
const LONGEST_UNIT_NANOSECONDS = {
|
|
16
|
+
hour: NANOSECONDS_PER_HOUR,
|
|
17
|
+
day: 24n * NANOSECONDS_PER_HOUR,
|
|
18
|
+
week: 168n * NANOSECONDS_PER_HOUR,
|
|
19
|
+
month: 744n * NANOSECONDS_PER_HOUR,
|
|
20
|
+
};
|
|
21
|
+
/** Offset transitions read before the pre-count gives up and leaves the answer to the walk. */
|
|
22
|
+
const MAX_PRECOUNT_TRANSITIONS = 4_096;
|
|
23
|
+
/**
|
|
24
|
+
* True when `[start, end)` certainly touches more than `max` buckets of `unit`, decided from the span
|
|
25
|
+
* instead of stepping bucket by bucket (which costs milliseconds a step in some zones).
|
|
26
|
+
*
|
|
27
|
+
* Over a prefix of the range, the local wall clock runs continuously between offset transitions.
|
|
28
|
+
* Those stretches cover at least the prefix's length less every backward offset change, in at most
|
|
29
|
+
* one stretch more than there are transitions, and each stretch of wall clock holds at least
|
|
30
|
+
* `floor(length / LONGEST_UNIT_NANOSECONDS)` distinct unit starts, each the start of its own
|
|
31
|
+
* bucket before `end`. The count subtracts two per stretch for the partial units at its ends.
|
|
32
|
+
* The bound also holds for a count of distinct local dates, which the free-time walk keeps by
|
|
33
|
+
* folding a day that re-enters an earlier date: a date can re-enter only at an offset transition,
|
|
34
|
+
* where the two units dropped per stretch already sit, and the starts counted inside one stretch
|
|
35
|
+
* fall on strictly increasing dates.
|
|
36
|
+
* `false` means "not certain": the walk decides, exactly as before.
|
|
37
|
+
*/
|
|
38
|
+
export function certainlyTouchesMoreBuckets(startZoned, endZoned, unit, max) {
|
|
39
|
+
const unitNs = LONGEST_UNIT_NANOSECONDS[unit];
|
|
40
|
+
const startNs = startZoned.epochNanoseconds;
|
|
41
|
+
const prefixEndNs = [
|
|
42
|
+
endZoned.epochNanoseconds,
|
|
43
|
+
startNs + 2n * BigInt(max + 1) * unitNs,
|
|
44
|
+
].reduce((a, b) => (a < b ? a : b));
|
|
45
|
+
if (prefixEndNs - startNs <= BigInt(max) * unitNs) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
let backwardNs = 0n;
|
|
49
|
+
let transitions = 0;
|
|
50
|
+
try {
|
|
51
|
+
for (let current = startZoned, next = zonedNextTransition(current); next !== null && next.epochNanoseconds < prefixEndNs; current = next, next = zonedNextTransition(current)) {
|
|
52
|
+
if (++transitions > MAX_PRECOUNT_TRANSITIONS) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
const shift = BigInt(current.offsetNanoseconds - next.offsetNanoseconds);
|
|
56
|
+
backwardNs += shift > 0n ? shift : 0n;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
const wallStarts = (prefixEndNs - startNs - backwardNs) / unitNs;
|
|
63
|
+
return wallStarts - 2n * BigInt(transitions + 1) > BigInt(max);
|
|
64
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
2
|
+
/**
|
|
3
|
+
* How local time is read for a time zone argument: a Temporal time zone, plus the part of a stored
|
|
4
|
+
* UTC offset no time zone identifier can carry.
|
|
5
|
+
*
|
|
6
|
+
* A time zone identifier stops at minutes (TC39 Temporal §13.31, the RFC 9557 / ISO 8601 grammar:
|
|
7
|
+
* `TimeZoneIdentifier ::: UTCOffset[~SubMinutePrecision] | TimeZoneIANAName`), but a zone's real
|
|
8
|
+
* offset does not: `Africa/Monrovia` stood at `-00:44:30` until 1972, and `getTimeZoneOffset`
|
|
9
|
+
* returns it. A fixed offset is still a complete rule for local time, so a function whose result
|
|
10
|
+
* names no zone reads one at any precision.
|
|
11
|
+
*
|
|
12
|
+
* The real offset is the offset of `timeZone` plus `shiftNanoseconds`. One frame serves a whole
|
|
13
|
+
* call, so every value of the call is placed in the same zone.
|
|
14
|
+
*/
|
|
15
|
+
export type ZoneFrame = {
|
|
16
|
+
/**
|
|
17
|
+
* A Temporal time zone identifier. For an offset with seconds it is the offset's whole minutes
|
|
18
|
+
* (`-00:44` for `-00:44:30`, `+02:10` for `+02:10:08`, `+00:00` within a minute of zero).
|
|
19
|
+
*/
|
|
20
|
+
timeZone: string;
|
|
21
|
+
/**
|
|
22
|
+
* `0n`, or the seconds the real offset has beyond the offset of `timeZone`, in nanoseconds:
|
|
23
|
+
* under a minute, with the offset's own sign (east positive).
|
|
24
|
+
*/
|
|
25
|
+
shiftNanoseconds: bigint;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Read a time zone argument that may also be a stored UTC offset.
|
|
29
|
+
*
|
|
30
|
+
* The only place that turns "time zone identifier or stored offset" into something Temporal can
|
|
31
|
+
* use. It accepts exactly what `isValidTimeZone` or `isValidUtcOffset` accepts, by five rules in
|
|
32
|
+
* order:
|
|
33
|
+
*
|
|
34
|
+
* 1. Not a string: null.
|
|
35
|
+
* 2. A time zone identifier (`isValidTimeZone`): that identifier as written, no shift. Every
|
|
36
|
+
* argument that was valid before stored offsets were read takes this branch.
|
|
37
|
+
* 3. Not a stored offset (`±HH:MM[:SS]`): null.
|
|
38
|
+
* 4. A whole number of minutes (`+05:30:00`): the identifier it canonicalises to (`+05:30`), no
|
|
39
|
+
* shift.
|
|
40
|
+
* 5. Otherwise (`-00:44:30`): the offset's whole minutes as the zone (`-00:44`), shifted by its
|
|
41
|
+
* seconds with the offset's own sign (30 seconds further west).
|
|
42
|
+
*
|
|
43
|
+
* - The returned `timeZone` is always a time zone identifier, so it is safe in a bracket or in
|
|
44
|
+
* `Intl.DateTimeFormat`. A seconds offset never becomes one: a caller that writes the zone into
|
|
45
|
+
* its result validates with `isValidTimeZone` instead and does not call this.
|
|
46
|
+
*
|
|
47
|
+
* @param zone the caller's time zone argument
|
|
48
|
+
* @returns the frame, or null when `zone` is neither a time zone identifier nor a stored offset
|
|
49
|
+
*
|
|
50
|
+
* @example zoneFrame("America/New_York") // { timeZone: "America/New_York", shiftNanoseconds: 0n }
|
|
51
|
+
* @example zoneFrame("+05:30:00") // { timeZone: "+05:30", shiftNanoseconds: 0n }
|
|
52
|
+
* @example zoneFrame("-00:44:30") // { timeZone: "-00:44", shiftNanoseconds: -30000000000n }
|
|
53
|
+
* @example zoneFrame("Z") // null
|
|
54
|
+
*/
|
|
55
|
+
export declare function zoneFrame(zone: unknown): ZoneFrame | null;
|
|
56
|
+
/**
|
|
57
|
+
* Read the `timeZone` option of a `unix/` or `utc/` function whose result names no zone.
|
|
58
|
+
*
|
|
59
|
+
* - Omitted (`undefined`) is `"UTC"`: an epoch and a UTC string name an instant, so no host zone
|
|
60
|
+
* is read unless asked for.
|
|
61
|
+
* - `"local"` is the system time zone, or null when the host reports none that is valid.
|
|
62
|
+
* - Anything else is read by `zoneFrame`.
|
|
63
|
+
*
|
|
64
|
+
* `normalizeTimeZone` is the twin for a function that writes the zone into its result or hands it
|
|
65
|
+
* to `Intl.DateTimeFormat`: it accepts a time zone identifier only.
|
|
66
|
+
*
|
|
67
|
+
* @param option the caller's `timeZone` option
|
|
68
|
+
* @returns the frame, or null when the option is invalid
|
|
69
|
+
*
|
|
70
|
+
* @example normalizeZoneFrame(undefined) // { timeZone: "UTC", shiftNanoseconds: 0n }
|
|
71
|
+
* @example normalizeZoneFrame("local") // the system zone, e.g. { timeZone: "America/New_York", shiftNanoseconds: 0n }
|
|
72
|
+
* @example normalizeZoneFrame("-00:44:30") // { timeZone: "-00:44", shiftNanoseconds: -30000000000n }
|
|
73
|
+
* @example normalizeZoneFrame("America/New_Yrok") // null
|
|
74
|
+
*/
|
|
75
|
+
export declare function normalizeZoneFrame(option?: unknown): ZoneFrame | null;
|
|
76
|
+
/**
|
|
77
|
+
* Read an instant on a frame's local wall clock. For a function that only reads fields.
|
|
78
|
+
*
|
|
79
|
+
* - A seconds offset is read with `wallClockAtOffset`, which is exact up to both limits of the
|
|
80
|
+
* instant range; `frameZoned` is not.
|
|
81
|
+
*
|
|
82
|
+
* Throws what Temporal throws; callers wrap it in their own try/catch.
|
|
83
|
+
*
|
|
84
|
+
* @param instant the exact time
|
|
85
|
+
* @param frame the frame from `zoneFrame`
|
|
86
|
+
* @returns the local wall clock
|
|
87
|
+
*
|
|
88
|
+
* @example frameWallClock(Temporal.Instant.from("1970-01-01T12:44:30Z"), zoneFrame("-00:44:30")).toString() // "1970-01-01T12:00:00"
|
|
89
|
+
*/
|
|
90
|
+
export declare function frameWallClock(instant: Temporal.Instant, frame: ZoneFrame): Temporal.PlainDateTime;
|
|
91
|
+
/**
|
|
92
|
+
* Read the current instant on a frame's local wall clock.
|
|
93
|
+
*
|
|
94
|
+
* Throws what Temporal throws; callers wrap it in their own try/catch.
|
|
95
|
+
*
|
|
96
|
+
* @param frame the frame from `zoneFrame`
|
|
97
|
+
* @returns the local wall clock now
|
|
98
|
+
*
|
|
99
|
+
* @example frameNowWallClock(zoneFrame("-00:44:30")).toPlainDate().toString() // today's date at -00:44:30
|
|
100
|
+
*/
|
|
101
|
+
export declare function frameNowWallClock(frame: ZoneFrame): Temporal.PlainDateTime;
|
|
102
|
+
/**
|
|
103
|
+
* Place an instant on a frame's local clock as a `Temporal.ZonedDateTime`, for a body that does
|
|
104
|
+
* arithmetic on one.
|
|
105
|
+
*
|
|
106
|
+
* - For a seconds offset the value sits in the frame's minute zone, at the instant plus the
|
|
107
|
+
* shift, so its wall clock is the real local one. At a constant offset, arithmetic on the wall
|
|
108
|
+
* clock is the same in any fixed-offset zone, and a day is always 24 hours. Its own
|
|
109
|
+
* `epochNanoseconds`, `offset` and `timeZoneId` are not the real ones: turn a result back with
|
|
110
|
+
* `frameInstant`, and never write it as a string.
|
|
111
|
+
* - Every value of one call is placed with the same frame, so all of them sit in one zone and
|
|
112
|
+
* are off by the same shift. Comparing their `epochNanoseconds`, and `until` between them, give
|
|
113
|
+
* what the real instants give.
|
|
114
|
+
* - Throws `RangeError` when the instant plus the shift is outside the instant range: within the
|
|
115
|
+
* shift's length, under a minute, of the last instant for an offset east of UTC, and of the
|
|
116
|
+
* first for one west. The caller returns its sentinel there, and its JSDoc says so. A function
|
|
117
|
+
* that only reads fields uses `frameWallClock`, which has no such edge.
|
|
118
|
+
*
|
|
119
|
+
* Throws what Temporal throws; callers wrap it in their own try/catch.
|
|
120
|
+
*
|
|
121
|
+
* @param instant the exact time
|
|
122
|
+
* @param frame the frame from `zoneFrame`
|
|
123
|
+
* @returns the zoned date-time to compute with
|
|
124
|
+
*
|
|
125
|
+
* @example frameInstant(frameZoned(Temporal.Instant.from("1970-01-01T12:44:30Z"), zoneFrame("-00:44:30")).startOfDay(), zoneFrame("-00:44:30")).toString() // "1970-01-01T00:44:30Z"
|
|
126
|
+
*/
|
|
127
|
+
export declare function frameZoned(instant: Temporal.Instant, frame: ZoneFrame): Temporal.ZonedDateTime;
|
|
128
|
+
/**
|
|
129
|
+
* The real epoch nanoseconds of a value `frameZoned` produced, or one computed from it.
|
|
130
|
+
*
|
|
131
|
+
* @param zoned a zoned date-time on the frame's local clock
|
|
132
|
+
* @param frame the frame it was placed on
|
|
133
|
+
* @returns epoch nanoseconds of the instant it names
|
|
134
|
+
*
|
|
135
|
+
* @example frameEpochNanoseconds(frameZoned(Temporal.Instant.from("1970-01-01T12:44:30Z"), zoneFrame("-00:44:30")), zoneFrame("-00:44:30")) // 45870000000000n
|
|
136
|
+
*/
|
|
137
|
+
export declare function frameEpochNanoseconds(zoned: Temporal.ZonedDateTime, frame: ZoneFrame): bigint;
|
|
138
|
+
/**
|
|
139
|
+
* The real instant of a value `frameZoned` produced, or one computed from it.
|
|
140
|
+
*
|
|
141
|
+
* Throws `RangeError` when the instant is outside Temporal's range; callers wrap it in their own
|
|
142
|
+
* try/catch.
|
|
143
|
+
*
|
|
144
|
+
* @param zoned a zoned date-time on the frame's local clock
|
|
145
|
+
* @param frame the frame it was placed on
|
|
146
|
+
* @returns the instant it names
|
|
147
|
+
*
|
|
148
|
+
* @example frameInstant(frameZoned(Temporal.Instant.from("1970-01-01T12:44:30Z"), zoneFrame("-00:44:30")), zoneFrame("-00:44:30")).toString() // "1970-01-01T12:44:30Z"
|
|
149
|
+
*/
|
|
150
|
+
export declare function frameInstant(zoned: Temporal.ZonedDateTime, frame: ZoneFrame): Temporal.Instant;
|
|
151
|
+
/**
|
|
152
|
+
* A frame's stored offset as text: `±HH:MM:SS` for a seconds offset.
|
|
153
|
+
*
|
|
154
|
+
* Throws `RangeError` for a frame with no shift, whose offset is its zone's to give; callers wrap
|
|
155
|
+
* it in their own try/catch.
|
|
156
|
+
*
|
|
157
|
+
* @param frame a frame whose `shiftNanoseconds` is not `0n`
|
|
158
|
+
* @returns the offset string
|
|
159
|
+
*
|
|
160
|
+
* @example frameOffset(zoneFrame("-00:44:30")) // "-00:44:30"
|
|
161
|
+
*/
|
|
162
|
+
export declare function frameOffset(frame: ZoneFrame): string;
|
|
163
|
+
/**
|
|
164
|
+
* The instant a local wall time names at a frame's stored offset.
|
|
165
|
+
*
|
|
166
|
+
* The wall time and the offset are joined into one date-time string and read by Temporal, which
|
|
167
|
+
* reads an offset with seconds there (TC39 Temporal §13.31,
|
|
168
|
+
* `DateTimeUTCOffset[Z] ::: [+Z] UTCDesignator | UTCOffset[+SubMinutePrecision]`). A fixed offset has no
|
|
169
|
+
* transition, so the wall time is never repeated or skipped and there is nothing to disambiguate.
|
|
170
|
+
* Exact up to both limits of the instant range.
|
|
171
|
+
*
|
|
172
|
+
* Throws what Temporal throws; callers wrap it in their own try/catch.
|
|
173
|
+
*
|
|
174
|
+
* @param wallClock an ISO 8601 `<date>T<time>` body with no offset and no annotation
|
|
175
|
+
* @param frame a frame whose `shiftNanoseconds` is not `0n`
|
|
176
|
+
* @returns the instant
|
|
177
|
+
*
|
|
178
|
+
* @example instantOfWallClock("1970-01-01T12:00:00", zoneFrame("-00:44:30")).toString() // "1970-01-01T12:44:30Z"
|
|
179
|
+
*/
|
|
180
|
+
export declare function instantOfWallClock(wallClock: string, frame: ZoneFrame): Temporal.Instant;
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
2
|
+
import { getSystemTimeZone } from "../zoned/get/getSystemTimeZone.js";
|
|
3
|
+
import { isValidTimeZone } from "../zoned/validate/isValidTimeZone.js";
|
|
4
|
+
import { instantFrom } from "./instantNanoseconds.js";
|
|
5
|
+
import { formatUtcOffset, parseUtcOffsetNanoseconds } from "./utcOffsetString.js";
|
|
6
|
+
import { wallClockAtOffset } from "./wallClockAtOffset.js";
|
|
7
|
+
const NANOSECONDS_PER_MINUTE = 60000000000n;
|
|
8
|
+
/**
|
|
9
|
+
* Read a time zone argument that may also be a stored UTC offset.
|
|
10
|
+
*
|
|
11
|
+
* The only place that turns "time zone identifier or stored offset" into something Temporal can
|
|
12
|
+
* use. It accepts exactly what `isValidTimeZone` or `isValidUtcOffset` accepts, by five rules in
|
|
13
|
+
* order:
|
|
14
|
+
*
|
|
15
|
+
* 1. Not a string: null.
|
|
16
|
+
* 2. A time zone identifier (`isValidTimeZone`): that identifier as written, no shift. Every
|
|
17
|
+
* argument that was valid before stored offsets were read takes this branch.
|
|
18
|
+
* 3. Not a stored offset (`±HH:MM[:SS]`): null.
|
|
19
|
+
* 4. A whole number of minutes (`+05:30:00`): the identifier it canonicalises to (`+05:30`), no
|
|
20
|
+
* shift.
|
|
21
|
+
* 5. Otherwise (`-00:44:30`): the offset's whole minutes as the zone (`-00:44`), shifted by its
|
|
22
|
+
* seconds with the offset's own sign (30 seconds further west).
|
|
23
|
+
*
|
|
24
|
+
* - The returned `timeZone` is always a time zone identifier, so it is safe in a bracket or in
|
|
25
|
+
* `Intl.DateTimeFormat`. A seconds offset never becomes one: a caller that writes the zone into
|
|
26
|
+
* its result validates with `isValidTimeZone` instead and does not call this.
|
|
27
|
+
*
|
|
28
|
+
* @param zone the caller's time zone argument
|
|
29
|
+
* @returns the frame, or null when `zone` is neither a time zone identifier nor a stored offset
|
|
30
|
+
*
|
|
31
|
+
* @example zoneFrame("America/New_York") // { timeZone: "America/New_York", shiftNanoseconds: 0n }
|
|
32
|
+
* @example zoneFrame("+05:30:00") // { timeZone: "+05:30", shiftNanoseconds: 0n }
|
|
33
|
+
* @example zoneFrame("-00:44:30") // { timeZone: "-00:44", shiftNanoseconds: -30000000000n }
|
|
34
|
+
* @example zoneFrame("Z") // null
|
|
35
|
+
*/
|
|
36
|
+
export function zoneFrame(zone) {
|
|
37
|
+
if (typeof zone !== "string") {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
if (isValidTimeZone(zone)) {
|
|
41
|
+
return { timeZone: zone, shiftNanoseconds: 0n };
|
|
42
|
+
}
|
|
43
|
+
const offsetNanoseconds = parseUtcOffsetNanoseconds(zone);
|
|
44
|
+
if (offsetNanoseconds === null) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
// BigInt remainder keeps the dividend's sign, so this is the offset's seconds with its sign,
|
|
48
|
+
// and what is left is its whole minutes: the minute offset between it and zero.
|
|
49
|
+
const shiftNanoseconds = offsetNanoseconds % NANOSECONDS_PER_MINUTE;
|
|
50
|
+
const timeZone = formatUtcOffset(offsetNanoseconds - shiftNanoseconds);
|
|
51
|
+
return timeZone === null ? null : { timeZone, shiftNanoseconds };
|
|
52
|
+
}
|
|
53
|
+
/** The real offset of a frame with a shift: its minute zone's offset plus the shift. */
|
|
54
|
+
function frameOffsetNanoseconds(frame) {
|
|
55
|
+
// The zone of a shifted frame is one `zoneFrame` wrote with `formatUtcOffset`, so it reads back.
|
|
56
|
+
const zoneOffset = parseUtcOffsetNanoseconds(frame.timeZone);
|
|
57
|
+
if (frame.shiftNanoseconds === 0n || zoneOffset === null) {
|
|
58
|
+
throw new RangeError("the frame carries no stored offset");
|
|
59
|
+
}
|
|
60
|
+
return zoneOffset + frame.shiftNanoseconds;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Read the `timeZone` option of a `unix/` or `utc/` function whose result names no zone.
|
|
64
|
+
*
|
|
65
|
+
* - Omitted (`undefined`) is `"UTC"`: an epoch and a UTC string name an instant, so no host zone
|
|
66
|
+
* is read unless asked for.
|
|
67
|
+
* - `"local"` is the system time zone, or null when the host reports none that is valid.
|
|
68
|
+
* - Anything else is read by `zoneFrame`.
|
|
69
|
+
*
|
|
70
|
+
* `normalizeTimeZone` is the twin for a function that writes the zone into its result or hands it
|
|
71
|
+
* to `Intl.DateTimeFormat`: it accepts a time zone identifier only.
|
|
72
|
+
*
|
|
73
|
+
* @param option the caller's `timeZone` option
|
|
74
|
+
* @returns the frame, or null when the option is invalid
|
|
75
|
+
*
|
|
76
|
+
* @example normalizeZoneFrame(undefined) // { timeZone: "UTC", shiftNanoseconds: 0n }
|
|
77
|
+
* @example normalizeZoneFrame("local") // the system zone, e.g. { timeZone: "America/New_York", shiftNanoseconds: 0n }
|
|
78
|
+
* @example normalizeZoneFrame("-00:44:30") // { timeZone: "-00:44", shiftNanoseconds: -30000000000n }
|
|
79
|
+
* @example normalizeZoneFrame("America/New_Yrok") // null
|
|
80
|
+
*/
|
|
81
|
+
export function normalizeZoneFrame(option) {
|
|
82
|
+
if (option === undefined) {
|
|
83
|
+
return { timeZone: "UTC", shiftNanoseconds: 0n };
|
|
84
|
+
}
|
|
85
|
+
return zoneFrame(option === "local" ? getSystemTimeZone() : option);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Read an instant on a frame's local wall clock. For a function that only reads fields.
|
|
89
|
+
*
|
|
90
|
+
* - A seconds offset is read with `wallClockAtOffset`, which is exact up to both limits of the
|
|
91
|
+
* instant range; `frameZoned` is not.
|
|
92
|
+
*
|
|
93
|
+
* Throws what Temporal throws; callers wrap it in their own try/catch.
|
|
94
|
+
*
|
|
95
|
+
* @param instant the exact time
|
|
96
|
+
* @param frame the frame from `zoneFrame`
|
|
97
|
+
* @returns the local wall clock
|
|
98
|
+
*
|
|
99
|
+
* @example frameWallClock(Temporal.Instant.from("1970-01-01T12:44:30Z"), zoneFrame("-00:44:30")).toString() // "1970-01-01T12:00:00"
|
|
100
|
+
*/
|
|
101
|
+
export function frameWallClock(instant, frame) {
|
|
102
|
+
return frame.shiftNanoseconds === 0n
|
|
103
|
+
? instant.toZonedDateTimeISO(frame.timeZone).toPlainDateTime()
|
|
104
|
+
: wallClockAtOffset(instant, frameOffsetNanoseconds(frame));
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Read the current instant on a frame's local wall clock.
|
|
108
|
+
*
|
|
109
|
+
* Throws what Temporal throws; callers wrap it in their own try/catch.
|
|
110
|
+
*
|
|
111
|
+
* @param frame the frame from `zoneFrame`
|
|
112
|
+
* @returns the local wall clock now
|
|
113
|
+
*
|
|
114
|
+
* @example frameNowWallClock(zoneFrame("-00:44:30")).toPlainDate().toString() // today's date at -00:44:30
|
|
115
|
+
*/
|
|
116
|
+
export function frameNowWallClock(frame) {
|
|
117
|
+
return frame.shiftNanoseconds === 0n
|
|
118
|
+
? Temporal.Now.zonedDateTimeISO(frame.timeZone).toPlainDateTime()
|
|
119
|
+
: wallClockAtOffset(Temporal.Now.instant(), frameOffsetNanoseconds(frame));
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Place an instant on a frame's local clock as a `Temporal.ZonedDateTime`, for a body that does
|
|
123
|
+
* arithmetic on one.
|
|
124
|
+
*
|
|
125
|
+
* - For a seconds offset the value sits in the frame's minute zone, at the instant plus the
|
|
126
|
+
* shift, so its wall clock is the real local one. At a constant offset, arithmetic on the wall
|
|
127
|
+
* clock is the same in any fixed-offset zone, and a day is always 24 hours. Its own
|
|
128
|
+
* `epochNanoseconds`, `offset` and `timeZoneId` are not the real ones: turn a result back with
|
|
129
|
+
* `frameInstant`, and never write it as a string.
|
|
130
|
+
* - Every value of one call is placed with the same frame, so all of them sit in one zone and
|
|
131
|
+
* are off by the same shift. Comparing their `epochNanoseconds`, and `until` between them, give
|
|
132
|
+
* what the real instants give.
|
|
133
|
+
* - Throws `RangeError` when the instant plus the shift is outside the instant range: within the
|
|
134
|
+
* shift's length, under a minute, of the last instant for an offset east of UTC, and of the
|
|
135
|
+
* first for one west. The caller returns its sentinel there, and its JSDoc says so. A function
|
|
136
|
+
* that only reads fields uses `frameWallClock`, which has no such edge.
|
|
137
|
+
*
|
|
138
|
+
* Throws what Temporal throws; callers wrap it in their own try/catch.
|
|
139
|
+
*
|
|
140
|
+
* @param instant the exact time
|
|
141
|
+
* @param frame the frame from `zoneFrame`
|
|
142
|
+
* @returns the zoned date-time to compute with
|
|
143
|
+
*
|
|
144
|
+
* @example frameInstant(frameZoned(Temporal.Instant.from("1970-01-01T12:44:30Z"), zoneFrame("-00:44:30")).startOfDay(), zoneFrame("-00:44:30")).toString() // "1970-01-01T00:44:30Z"
|
|
145
|
+
*/
|
|
146
|
+
export function frameZoned(instant, frame) {
|
|
147
|
+
return frame.shiftNanoseconds === 0n
|
|
148
|
+
? instant.toZonedDateTimeISO(frame.timeZone)
|
|
149
|
+
: instant
|
|
150
|
+
.add({ nanoseconds: Number(frame.shiftNanoseconds) })
|
|
151
|
+
.toZonedDateTimeISO(frame.timeZone);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* The real epoch nanoseconds of a value `frameZoned` produced, or one computed from it.
|
|
155
|
+
*
|
|
156
|
+
* @param zoned a zoned date-time on the frame's local clock
|
|
157
|
+
* @param frame the frame it was placed on
|
|
158
|
+
* @returns epoch nanoseconds of the instant it names
|
|
159
|
+
*
|
|
160
|
+
* @example frameEpochNanoseconds(frameZoned(Temporal.Instant.from("1970-01-01T12:44:30Z"), zoneFrame("-00:44:30")), zoneFrame("-00:44:30")) // 45870000000000n
|
|
161
|
+
*/
|
|
162
|
+
export function frameEpochNanoseconds(zoned, frame) {
|
|
163
|
+
// The value was placed the shift later than its instant, so that the minute zone's wall clock
|
|
164
|
+
// is the real local one: local time = instant + offset (TC39 Temporal GetISODateTimeFor).
|
|
165
|
+
return zoned.epochNanoseconds - frame.shiftNanoseconds;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* The real instant of a value `frameZoned` produced, or one computed from it.
|
|
169
|
+
*
|
|
170
|
+
* Throws `RangeError` when the instant is outside Temporal's range; callers wrap it in their own
|
|
171
|
+
* try/catch.
|
|
172
|
+
*
|
|
173
|
+
* @param zoned a zoned date-time on the frame's local clock
|
|
174
|
+
* @param frame the frame it was placed on
|
|
175
|
+
* @returns the instant it names
|
|
176
|
+
*
|
|
177
|
+
* @example frameInstant(frameZoned(Temporal.Instant.from("1970-01-01T12:44:30Z"), zoneFrame("-00:44:30")), zoneFrame("-00:44:30")).toString() // "1970-01-01T12:44:30Z"
|
|
178
|
+
*/
|
|
179
|
+
export function frameInstant(zoned, frame) {
|
|
180
|
+
return frame.shiftNanoseconds === 0n
|
|
181
|
+
? zoned.toInstant()
|
|
182
|
+
: Temporal.Instant.fromEpochNanoseconds(frameEpochNanoseconds(zoned, frame));
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* A frame's stored offset as text: `±HH:MM:SS` for a seconds offset.
|
|
186
|
+
*
|
|
187
|
+
* Throws `RangeError` for a frame with no shift, whose offset is its zone's to give; callers wrap
|
|
188
|
+
* it in their own try/catch.
|
|
189
|
+
*
|
|
190
|
+
* @param frame a frame whose `shiftNanoseconds` is not `0n`
|
|
191
|
+
* @returns the offset string
|
|
192
|
+
*
|
|
193
|
+
* @example frameOffset(zoneFrame("-00:44:30")) // "-00:44:30"
|
|
194
|
+
*/
|
|
195
|
+
export function frameOffset(frame) {
|
|
196
|
+
const offset = formatUtcOffset(frameOffsetNanoseconds(frame));
|
|
197
|
+
if (offset === null) {
|
|
198
|
+
throw new RangeError("the frame carries no stored offset");
|
|
199
|
+
}
|
|
200
|
+
return offset;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* The instant a local wall time names at a frame's stored offset.
|
|
204
|
+
*
|
|
205
|
+
* The wall time and the offset are joined into one date-time string and read by Temporal, which
|
|
206
|
+
* reads an offset with seconds there (TC39 Temporal §13.31,
|
|
207
|
+
* `DateTimeUTCOffset[Z] ::: [+Z] UTCDesignator | UTCOffset[+SubMinutePrecision]`). A fixed offset has no
|
|
208
|
+
* transition, so the wall time is never repeated or skipped and there is nothing to disambiguate.
|
|
209
|
+
* Exact up to both limits of the instant range.
|
|
210
|
+
*
|
|
211
|
+
* Throws what Temporal throws; callers wrap it in their own try/catch.
|
|
212
|
+
*
|
|
213
|
+
* @param wallClock an ISO 8601 `<date>T<time>` body with no offset and no annotation
|
|
214
|
+
* @param frame a frame whose `shiftNanoseconds` is not `0n`
|
|
215
|
+
* @returns the instant
|
|
216
|
+
*
|
|
217
|
+
* @example instantOfWallClock("1970-01-01T12:00:00", zoneFrame("-00:44:30")).toString() // "1970-01-01T12:44:30Z"
|
|
218
|
+
*/
|
|
219
|
+
export function instantOfWallClock(wallClock, frame) {
|
|
220
|
+
return instantFrom(`${wallClock}${frameOffset(frame)}`);
|
|
221
|
+
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
/**
|
|
3
3
|
* One field of a zoned "now" as the `get*NowUnit` accessors return it: zero-padded to two digits
|
|
4
|
-
* (three for sub-second fields), the
|
|
4
|
+
* (three for sub-second fields), the day of week unpadded, and the year as Temporal writes one
|
|
5
|
+
* (`isoYearString`: four digits, or a sign and six outside 0000–9999). The week number is the
|
|
5
6
|
* caller's, since the plain and zoned accessors read it through `parseWeekFromDate` and the utc and
|
|
6
7
|
* unix ones from the ISO date.
|
|
7
8
|
*
|
|
8
|
-
* @param now the current moment on the wall clock being read
|
|
9
|
+
* @param now the current moment on the wall clock being read: a zoned date-time, or the plain wall
|
|
10
|
+
* clock of a stored UTC offset with seconds, which no time zone identifier can carry
|
|
9
11
|
* @param unit a singular unit, `dayOfWeek` included (already validated by the caller)
|
|
10
12
|
* @param week the week number for `now`, as a string
|
|
11
13
|
* @returns the field, or "" for any other unit
|
|
@@ -13,11 +15,12 @@ import { Temporal } from "@js-temporal/polyfill";
|
|
|
13
15
|
* @example zonedNowUnitValue(Temporal.ZonedDateTime.from("2024-03-05T07:08:09+00:00[UTC]"), "week", () => "10") // "10"
|
|
14
16
|
* @example zonedNowUnitValue(Temporal.ZonedDateTime.from("2024-03-05T07:08:09+00:00[UTC]"), "quarter", () => "10") // ""
|
|
15
17
|
*/
|
|
16
|
-
export declare function zonedNowUnitValue(now:
|
|
18
|
+
export declare function zonedNowUnitValue<Clock extends Temporal.ZonedDateTime | Temporal.PlainDateTime>(now: Clock, unit: string | null | undefined, week: (now: Clock) => string): string;
|
|
17
19
|
/**
|
|
18
20
|
* The ISO 8601 week number of `now`'s date, the week the utc and unix `get*NowUnit` accessors read.
|
|
19
21
|
*
|
|
20
|
-
* @param now the current moment on the wall clock being read
|
|
22
|
+
* @param now the current moment on the wall clock being read: a zoned date-time, or the plain wall
|
|
23
|
+
* clock of a stored UTC offset with seconds, which no time zone identifier can carry
|
|
21
24
|
* @returns the week number as a string
|
|
22
25
|
* @example isoWeekOfYear(Temporal.ZonedDateTime.from("2024-12-30T00:00:00+00:00[UTC]")) // "1"
|
|
23
26
|
*/
|