@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,68 @@
|
|
|
1
|
+
import { readEdiValue } from "../../internal/ediDateTimeFields.js";
|
|
2
|
+
/**
|
|
3
|
+
* Parse a UN/EDIFACT `DTM` value that states a date and a time with an offset from UTC, as an
|
|
4
|
+
* ISO 8601 date-time with its offset.
|
|
5
|
+
*
|
|
6
|
+
* A `DTM` segment carries its value in data element **2380** and, in data element **2379**, the
|
|
7
|
+
* format code that says how to read it. This function reads the codes whose value names an
|
|
8
|
+
* instant. Masks and descriptions are the UNTDID directory's, read from
|
|
9
|
+
* [UNECE's D.21B page as archived](http://web.archive.org/web/20240303123657/https://service.unece.org/trade/untdid/d21b/tred/tred2379.htm).
|
|
10
|
+
*
|
|
11
|
+
* ### Format codes
|
|
12
|
+
* | Code | Mask | The directory's description |
|
|
13
|
+
* |---|---|---|
|
|
14
|
+
* | `205` | `CCYYMMDDHHMMZHHMM` | "Calendar date including time and time zone expressed in hours and minutes." |
|
|
15
|
+
* | `208` | `CCYYMMDDHHMMSSZHHMM` | "Calendar date including time with seconds, with Time Zone" (D.12A and later) |
|
|
16
|
+
* | `303` | `CCYYMMDDHHMMZZZ` | "See 203 plus Z=Time zone." |
|
|
17
|
+
* | `304` | `CCYYMMDDHHMMSSZZZ` | "See 204 plus Z=Time zone." |
|
|
18
|
+
*
|
|
19
|
+
* - **The result is the wall clock as written, with its offset**: `YYYY-MM-DDTHH:MM:SS±HH:MM`,
|
|
20
|
+
* on its own day and never moved to UTC. It is the string `fromOffsetInstant` writes, so
|
|
21
|
+
* `toOffsetInstant` reads it as the instant and the offset, and every function that takes an
|
|
22
|
+
* instant takes it.
|
|
23
|
+
* - **`ZHHMM` (`205`, `208`) is a sign, hours and minutes** (`+0200`, `-0330`). `-0000` is read
|
|
24
|
+
* as `+00:00`.
|
|
25
|
+
* - **`ZZZ` (`303`, `304`) is read as an offset only.** A signed hour from `00` to `23` (`+02`,
|
|
26
|
+
* `-05`) is that offset: UN/ECE Recommendation 7 ¶12 appends the difference from UTC "in hours
|
|
27
|
+
* and minutes, or hours only, with a leading "+" or "-" sign". The literals `UTC` and `GMT`
|
|
28
|
+
* are `+00:00`: the SMDG container-shipping guides write `UTC` in a `303` value, and
|
|
29
|
+
* Recommendation 7 ¶12 names one scale by both names, "Co-ordinated Universal Time (formerly
|
|
30
|
+
* known as Greenwich Mean Time)".
|
|
31
|
+
* - **Any other three characters return `""`**, letters such as `CET` included: the directory
|
|
32
|
+
* says only "Z = Time zone", no standard defines an abbreviation, and GMT does not guess what
|
|
33
|
+
* one means. Where a partner sends one, read the wall clock with `parseEdifactDateTime` after
|
|
34
|
+
* removing the three letters, and resolve it in the IANA zone you map them to with
|
|
35
|
+
* `resolveLocal`.
|
|
36
|
+
* - **Pass the unescaped element value.** `+` is the EDIFACT data element separator, so an
|
|
37
|
+
* interchange transmits `+02` as `?+02`. Remove the release character first:
|
|
38
|
+
* `"202406151430?+02"` returns `""`.
|
|
39
|
+
* - Seconds are always written in the result, `00` for `205` and `303`. Fields are checked, not
|
|
40
|
+
* clamped: hour 24, second 60 and 29 February 2023 return `""`.
|
|
41
|
+
* - A two-digit year (`206`, `207`, `301`, `302`) is not read.
|
|
42
|
+
* - Returns `""` for any other code, a code of another kind included (`203` is read by
|
|
43
|
+
* `parseEdifactDateTime`), and for a non-string argument.
|
|
44
|
+
*
|
|
45
|
+
* @param value The data element 2380 value, unescaped (e.g. "202406151430+0200")
|
|
46
|
+
* @param format The data element 2379 format code
|
|
47
|
+
* @returns the date-time with its offset as `YYYY-MM-DDTHH:MM:SS±HH:MM`, or "" on invalid input
|
|
48
|
+
*
|
|
49
|
+
* @example parseEdifactOffsetDateTime("202406151430+0200", "205") // "2024-06-15T14:30:00+02:00"
|
|
50
|
+
* @example parseEdifactOffsetDateTime("20240615143045+0530", "208") // "2024-06-15T14:30:45+05:30"
|
|
51
|
+
* @example parseEdifactOffsetDateTime("202406151430+02", "303") // "2024-06-15T14:30:00+02:00"
|
|
52
|
+
* @example parseEdifactOffsetDateTime("20240615143045-05", "304") // "2024-06-15T14:30:45-05:00"
|
|
53
|
+
* @example parseEdifactOffsetDateTime("202406151430UTC", "303") // "2024-06-15T14:30:00+00:00"
|
|
54
|
+
* @example parseEdifactOffsetDateTime("202406151430GMT", "303") // "2024-06-15T14:30:00+00:00"
|
|
55
|
+
* @example parseEdifactOffsetDateTime("202406151430CET", "303") // "" (an abbreviation names no offset)
|
|
56
|
+
* @example parseEdifactOffsetDateTime("202406151430+24", "303") // "" (not a signed hour)
|
|
57
|
+
* @example parseEdifactOffsetDateTime("202406151430?+02", "303") // "" (the release character is the caller's to remove)
|
|
58
|
+
* @example parseEdifactOffsetDateTime("202406151430", "203") // "" (a local code: use parseEdifactDateTime)
|
|
59
|
+
*/
|
|
60
|
+
export function parseEdifactOffsetDateTime(value, format) {
|
|
61
|
+
try {
|
|
62
|
+
return readEdiValue("edifact", "offsetDateTime", format, value);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// Never throws (Core Rule 3): a hostile argument is invalid input, not an exception.
|
|
66
|
+
return "";
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { EdifactTimeFormat } from "../../types/edi.js";
|
|
2
|
+
/**
|
|
3
|
+
* Parse a UN/EDIFACT `DTM` value that states a time of day, as an ISO 8601 time.
|
|
4
|
+
*
|
|
5
|
+
* A `DTM` segment carries its value in data element **2380** and, in data element **2379**, the
|
|
6
|
+
* format code that says how to read it. This function reads the codes whose value is a time
|
|
7
|
+
* with no date and no offset. Masks and descriptions are the UNTDID directory's, read from
|
|
8
|
+
* [UNECE's D.21B page as archived](http://web.archive.org/web/20240303123657/https://service.unece.org/trade/untdid/d21b/tred/tred2379.htm).
|
|
9
|
+
*
|
|
10
|
+
* ### Format codes
|
|
11
|
+
* | Code | Mask | The directory's description |
|
|
12
|
+
* |---|---|---|
|
|
13
|
+
* | `401` | `HHMM` | "Time without seconds: H = Hour; m = Minute." |
|
|
14
|
+
* | `402` | `HHMMSS` | "Time with seconds: H = Hour; m = Minute; s = Seconds." |
|
|
15
|
+
*
|
|
16
|
+
* - The value must be the digits of its code's mask: `"1430"` is a `401` value and not a `402`
|
|
17
|
+
* one.
|
|
18
|
+
* - Seconds are always written in the result, `00` for `401`.
|
|
19
|
+
* - Fields are checked, not clamped: hour 24, minute 60 and second 60 return `""`.
|
|
20
|
+
* - A time with an offset (`209`, `404`) is not read: with no date it names no instant. Read
|
|
21
|
+
* the date and time together with `parseEdifactOffsetDateTime` where the partner sends `205`,
|
|
22
|
+
* `208`, `303` or `304`.
|
|
23
|
+
* - Returns `""` for any other code, a code of another kind included, and for a non-string
|
|
24
|
+
* argument.
|
|
25
|
+
*
|
|
26
|
+
* @param value The data element 2380 value (e.g. "1430")
|
|
27
|
+
* @param format The data element 2379 format code
|
|
28
|
+
* @returns the time as `HH:MM:SS`, or "" on invalid input
|
|
29
|
+
*
|
|
30
|
+
* @example parseEdifactTime("1430", "401") // "14:30:00"
|
|
31
|
+
* @example parseEdifactTime("143045", "402") // "14:30:45"
|
|
32
|
+
* @example parseEdifactTime("143045", "401") // "" (six digits is a 402 value)
|
|
33
|
+
* @example parseEdifactTime("2400", "401") // "" (hour 24)
|
|
34
|
+
* @example parseEdifactTime("14:30", "401") // "" (the value is the digits of the mask)
|
|
35
|
+
* @example parseEdifactTime("20240615", "102") // "" (a date code: use parseEdifactDate)
|
|
36
|
+
*/
|
|
37
|
+
export declare function parseEdifactTime(value: string, format: EdifactTimeFormat): string;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { readEdiValue } from "../../internal/ediDateTimeFields.js";
|
|
2
|
+
/**
|
|
3
|
+
* Parse a UN/EDIFACT `DTM` value that states a time of day, as an ISO 8601 time.
|
|
4
|
+
*
|
|
5
|
+
* A `DTM` segment carries its value in data element **2380** and, in data element **2379**, the
|
|
6
|
+
* format code that says how to read it. This function reads the codes whose value is a time
|
|
7
|
+
* with no date and no offset. Masks and descriptions are the UNTDID directory's, read from
|
|
8
|
+
* [UNECE's D.21B page as archived](http://web.archive.org/web/20240303123657/https://service.unece.org/trade/untdid/d21b/tred/tred2379.htm).
|
|
9
|
+
*
|
|
10
|
+
* ### Format codes
|
|
11
|
+
* | Code | Mask | The directory's description |
|
|
12
|
+
* |---|---|---|
|
|
13
|
+
* | `401` | `HHMM` | "Time without seconds: H = Hour; m = Minute." |
|
|
14
|
+
* | `402` | `HHMMSS` | "Time with seconds: H = Hour; m = Minute; s = Seconds." |
|
|
15
|
+
*
|
|
16
|
+
* - The value must be the digits of its code's mask: `"1430"` is a `401` value and not a `402`
|
|
17
|
+
* one.
|
|
18
|
+
* - Seconds are always written in the result, `00` for `401`.
|
|
19
|
+
* - Fields are checked, not clamped: hour 24, minute 60 and second 60 return `""`.
|
|
20
|
+
* - A time with an offset (`209`, `404`) is not read: with no date it names no instant. Read
|
|
21
|
+
* the date and time together with `parseEdifactOffsetDateTime` where the partner sends `205`,
|
|
22
|
+
* `208`, `303` or `304`.
|
|
23
|
+
* - Returns `""` for any other code, a code of another kind included, and for a non-string
|
|
24
|
+
* argument.
|
|
25
|
+
*
|
|
26
|
+
* @param value The data element 2380 value (e.g. "1430")
|
|
27
|
+
* @param format The data element 2379 format code
|
|
28
|
+
* @returns the time as `HH:MM:SS`, or "" on invalid input
|
|
29
|
+
*
|
|
30
|
+
* @example parseEdifactTime("1430", "401") // "14:30:00"
|
|
31
|
+
* @example parseEdifactTime("143045", "402") // "14:30:45"
|
|
32
|
+
* @example parseEdifactTime("143045", "401") // "" (six digits is a 402 value)
|
|
33
|
+
* @example parseEdifactTime("2400", "401") // "" (hour 24)
|
|
34
|
+
* @example parseEdifactTime("14:30", "401") // "" (the value is the digits of the mask)
|
|
35
|
+
* @example parseEdifactTime("20240615", "102") // "" (a date code: use parseEdifactDate)
|
|
36
|
+
*/
|
|
37
|
+
export function parseEdifactTime(value, format) {
|
|
38
|
+
try {
|
|
39
|
+
return readEdiValue("edifact", "time", format, value);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// Never throws (Core Rule 3): a hostile argument is invalid input, not an exception.
|
|
43
|
+
return "";
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { EpcisEventTime } from "../../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* When a GS1 EPCIS 2.0 event happened, read three ways: the instant, the UTC offset in force
|
|
4
|
+
* where it happened, and the local wall clock there. The result of `parseEpcisEvent`.
|
|
5
|
+
*
|
|
6
|
+
* `instant` and `offset` are the pair `formatEpcisEvent` and `fromOffsetInstant` take, so the
|
|
7
|
+
* result can be passed to either as it is.
|
|
8
|
+
*/
|
|
9
|
+
export interface EpcisInstant {
|
|
10
|
+
/**
|
|
11
|
+
* The moment the event happened, as an ISO 8601 instant in UTC ending in `Z`
|
|
12
|
+
* (`2024-06-15T14:30:00Z`). It orders events from every site on one timeline. A fraction is
|
|
13
|
+
* kept to the nanosecond and written without trailing zeros. An `eventTime` whose own offset
|
|
14
|
+
* carries it across either end of years 0000–9999 gives an instant with a sign and a
|
|
15
|
+
* six-digit year.
|
|
16
|
+
*/
|
|
17
|
+
instant: string;
|
|
18
|
+
/**
|
|
19
|
+
* The UTC offset in force where the event happened, `±HH:MM`: the event's
|
|
20
|
+
* `eventTimeZoneOffset`, with `-00:00` written as `+00:00`. It is an offset and not a zone, so
|
|
21
|
+
* it says nothing about the local time of any other event.
|
|
22
|
+
*/
|
|
23
|
+
offset: string;
|
|
24
|
+
/**
|
|
25
|
+
* The date and time on the local clock where the event happened,
|
|
26
|
+
* `YYYY-MM-DDTHH:MM:SS[.fraction]` with no offset: `instant` shown at `offset`. Its date can be
|
|
27
|
+
* the day before or after the UTC date. A year outside 0000–9999, reachable only within 14
|
|
28
|
+
* hours of either end of the four-digit range, is written with a sign and six digits.
|
|
29
|
+
*/
|
|
30
|
+
local: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Read the two required time fields of a GS1 EPCIS 2.0 event as an instant, the UTC offset in
|
|
34
|
+
* force where the event happened, and the local wall clock there.
|
|
35
|
+
*
|
|
36
|
+
* EPCIS (ISO/IEC 19987) is GS1's event standard for supply-chain visibility: each event records
|
|
37
|
+
* what happened to which objects, where, when and why.
|
|
38
|
+
*
|
|
39
|
+
* - **Both fields are required**, as the EPCIS JSON schema requires them. `eventTime` fixes the
|
|
40
|
+
* instant. `eventTimeZoneOffset` is the offset the local clock ran at where the event
|
|
41
|
+
* happened, kept so the event can be shown in local time. Neither derives from the other, so
|
|
42
|
+
* an event without `eventTimeZoneOffset` returns null: UTC is not assumed.
|
|
43
|
+
* - **Each field is checked against the stricter of the two bindings.** `eventTime` takes the
|
|
44
|
+
* XML binding's pattern (the XSD's `DateTimeStamp`; the JSON schema says only
|
|
45
|
+
* `format: date-time`). `eventTimeZoneOffset` takes the JSON schema's pattern (the XSD types
|
|
46
|
+
* it as a bare `xsd:string`), which is the rule the standard states in prose, EPCIS Standard
|
|
47
|
+
* Release 2.0 §7.4.1 (https://ref.gs1.org/standards/epcis/): an hour "within the range 00
|
|
48
|
+
* through 14 (inclusive) … except that if the value of the first two digits is 14, the value
|
|
49
|
+
* of the second two digits must be 00".
|
|
50
|
+
* - **`eventTime`** must match `epcisEventTime`, the `DateTimeStamp` pattern of the EPCIS XSD:
|
|
51
|
+
* `YYYY-MM-DDTHH:MM:SS`, an optional fraction, then `Z` or a `±HH:MM` offset up to `14:00`.
|
|
52
|
+
* Seconds are required, `T` and `Z` are upper-case, and nothing may follow: a space separator,
|
|
53
|
+
* a leap second (`:60`), an expanded year and a bracketed zone or annotation return null. The
|
|
54
|
+
* pattern checks shape only, so a day the month does not have (`2024-02-30`) is rejected by
|
|
55
|
+
* Temporal and returns null.
|
|
56
|
+
* - **`eventTimeZoneOffset`** must match `epcisTimeZoneOffset`, the pattern the EPCIS JSON schema
|
|
57
|
+
* gives: `±HH:MM` from `-14:00` to `+14:00`. `Z`, `+0200`, `+02` and an offset with seconds
|
|
58
|
+
* return null.
|
|
59
|
+
* - **The two fields are independent and need not agree.** `eventTime` may carry an offset of
|
|
60
|
+
* its own instead of `Z`; that offset only fixes the instant. The local clock always comes from
|
|
61
|
+
* `eventTimeZoneOffset`, and a difference between the two is not an error. EPCIS 2.0 §7.4.1.1,
|
|
62
|
+
* an explanation the standard marks non-normative: "there is no requirement that the time zone
|
|
63
|
+
* specifier in the XML representation of eventTime be the local time zone offset where the
|
|
64
|
+
* event was captured".
|
|
65
|
+
* - **An instant can fall outside years 0000–9999.** An `eventTime` whose own offset carries it
|
|
66
|
+
* across either end of the four-digit years names an instant just past it, written with a sign
|
|
67
|
+
* and a six-digit year, and `local` is written the same way when it falls outside.
|
|
68
|
+
* - `-00:00` matches the GS1 pattern and is returned as `+00:00`, as `toOffsetInstant` returns
|
|
69
|
+
* it. RFC 9557 §2.2 reads `-00:00` as "local offset unknown"; the result cannot say that.
|
|
70
|
+
* - **GMT rule: a fraction longer than nine digits returns null.** The XSD allows a fraction of
|
|
71
|
+
* any length and an instant holds nanoseconds. Dropping digits would report a time the event
|
|
72
|
+
* does not state, so the value is refused instead, trailing zeros included.
|
|
73
|
+
* - `local` is the instant shown at the offset, so its date can differ from the UTC date.
|
|
74
|
+
* - Only the two fields are read. `recordTime` and every other member of the event are ignored.
|
|
75
|
+
* - Returns null when `event` is not an object, when either field is missing or not a string,
|
|
76
|
+
* and for every case above.
|
|
77
|
+
*
|
|
78
|
+
* @param event an EPCIS event, or any object with its `eventTime` and `eventTimeZoneOffset`
|
|
79
|
+
* @returns `{ instant, offset, local }`, or null on invalid input
|
|
80
|
+
*
|
|
81
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T14:30:00Z", eventTimeZoneOffset: "-05:00" }) // { instant: "2024-06-15T14:30:00Z", offset: "-05:00", local: "2024-06-15T09:30:00" }
|
|
82
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T23:30:00Z", eventTimeZoneOffset: "+02:00" }) // { instant: "2024-06-15T23:30:00Z", offset: "+02:00", local: "2024-06-16T01:30:00" } (the local date is the next day)
|
|
83
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T10:00:00+02:00", eventTimeZoneOffset: "+02:00" }) // { instant: "2024-06-15T08:00:00Z", offset: "+02:00", local: "2024-06-15T10:00:00" }
|
|
84
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T10:00:00+02:00", eventTimeZoneOffset: "-05:00" }) // { instant: "2024-06-15T08:00:00Z", offset: "-05:00", local: "2024-06-15T03:00:00" } (the two offsets need not agree)
|
|
85
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T14:30:00.123456789Z", eventTimeZoneOffset: "+05:45" }) // { instant: "2024-06-15T14:30:00.123456789Z", offset: "+05:45", local: "2024-06-15T20:15:00.123456789" }
|
|
86
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T14:30:00Z", eventTimeZoneOffset: "-00:00" }) // { instant: "2024-06-15T14:30:00Z", offset: "+00:00", local: "2024-06-15T14:30:00" }
|
|
87
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T14:30:00Z" }) // null (eventTimeZoneOffset is required)
|
|
88
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T14:30:00Z", eventTimeZoneOffset: "Z" }) // null (a designator, not an offset)
|
|
89
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T14:30:00Z", eventTimeZoneOffset: "+0200" }) // null (no colon)
|
|
90
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T14:30Z", eventTimeZoneOffset: "+02:00" }) // null (seconds are required)
|
|
91
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15 14:30:00Z", eventTimeZoneOffset: "+02:00" }) // null (a space separator)
|
|
92
|
+
* @example parseEpcisEvent({ eventTime: "2024-02-30T14:30:00Z", eventTimeZoneOffset: "+02:00" }) // null (30 February)
|
|
93
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T14:30:00.1234567891Z", eventTimeZoneOffset: "+02:00" }) // null (finer than a nanosecond)
|
|
94
|
+
*/
|
|
95
|
+
export declare function parseEpcisEvent(event: EpcisEventTime): EpcisInstant | null;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
2
|
+
import { formatUtcOffset, isObject, parseUtcOffsetNanoseconds, wallClockAtOffset, } from "../../internal/index.js";
|
|
3
|
+
import { epcisEventTime, epcisTimeZoneOffset } from "../../regex/index.js";
|
|
4
|
+
/**
|
|
5
|
+
* Read the two required time fields of a GS1 EPCIS 2.0 event as an instant, the UTC offset in
|
|
6
|
+
* force where the event happened, and the local wall clock there.
|
|
7
|
+
*
|
|
8
|
+
* EPCIS (ISO/IEC 19987) is GS1's event standard for supply-chain visibility: each event records
|
|
9
|
+
* what happened to which objects, where, when and why.
|
|
10
|
+
*
|
|
11
|
+
* - **Both fields are required**, as the EPCIS JSON schema requires them. `eventTime` fixes the
|
|
12
|
+
* instant. `eventTimeZoneOffset` is the offset the local clock ran at where the event
|
|
13
|
+
* happened, kept so the event can be shown in local time. Neither derives from the other, so
|
|
14
|
+
* an event without `eventTimeZoneOffset` returns null: UTC is not assumed.
|
|
15
|
+
* - **Each field is checked against the stricter of the two bindings.** `eventTime` takes the
|
|
16
|
+
* XML binding's pattern (the XSD's `DateTimeStamp`; the JSON schema says only
|
|
17
|
+
* `format: date-time`). `eventTimeZoneOffset` takes the JSON schema's pattern (the XSD types
|
|
18
|
+
* it as a bare `xsd:string`), which is the rule the standard states in prose, EPCIS Standard
|
|
19
|
+
* Release 2.0 §7.4.1 (https://ref.gs1.org/standards/epcis/): an hour "within the range 00
|
|
20
|
+
* through 14 (inclusive) … except that if the value of the first two digits is 14, the value
|
|
21
|
+
* of the second two digits must be 00".
|
|
22
|
+
* - **`eventTime`** must match `epcisEventTime`, the `DateTimeStamp` pattern of the EPCIS XSD:
|
|
23
|
+
* `YYYY-MM-DDTHH:MM:SS`, an optional fraction, then `Z` or a `±HH:MM` offset up to `14:00`.
|
|
24
|
+
* Seconds are required, `T` and `Z` are upper-case, and nothing may follow: a space separator,
|
|
25
|
+
* a leap second (`:60`), an expanded year and a bracketed zone or annotation return null. The
|
|
26
|
+
* pattern checks shape only, so a day the month does not have (`2024-02-30`) is rejected by
|
|
27
|
+
* Temporal and returns null.
|
|
28
|
+
* - **`eventTimeZoneOffset`** must match `epcisTimeZoneOffset`, the pattern the EPCIS JSON schema
|
|
29
|
+
* gives: `±HH:MM` from `-14:00` to `+14:00`. `Z`, `+0200`, `+02` and an offset with seconds
|
|
30
|
+
* return null.
|
|
31
|
+
* - **The two fields are independent and need not agree.** `eventTime` may carry an offset of
|
|
32
|
+
* its own instead of `Z`; that offset only fixes the instant. The local clock always comes from
|
|
33
|
+
* `eventTimeZoneOffset`, and a difference between the two is not an error. EPCIS 2.0 §7.4.1.1,
|
|
34
|
+
* an explanation the standard marks non-normative: "there is no requirement that the time zone
|
|
35
|
+
* specifier in the XML representation of eventTime be the local time zone offset where the
|
|
36
|
+
* event was captured".
|
|
37
|
+
* - **An instant can fall outside years 0000–9999.** An `eventTime` whose own offset carries it
|
|
38
|
+
* across either end of the four-digit years names an instant just past it, written with a sign
|
|
39
|
+
* and a six-digit year, and `local` is written the same way when it falls outside.
|
|
40
|
+
* - `-00:00` matches the GS1 pattern and is returned as `+00:00`, as `toOffsetInstant` returns
|
|
41
|
+
* it. RFC 9557 §2.2 reads `-00:00` as "local offset unknown"; the result cannot say that.
|
|
42
|
+
* - **GMT rule: a fraction longer than nine digits returns null.** The XSD allows a fraction of
|
|
43
|
+
* any length and an instant holds nanoseconds. Dropping digits would report a time the event
|
|
44
|
+
* does not state, so the value is refused instead, trailing zeros included.
|
|
45
|
+
* - `local` is the instant shown at the offset, so its date can differ from the UTC date.
|
|
46
|
+
* - Only the two fields are read. `recordTime` and every other member of the event are ignored.
|
|
47
|
+
* - Returns null when `event` is not an object, when either field is missing or not a string,
|
|
48
|
+
* and for every case above.
|
|
49
|
+
*
|
|
50
|
+
* @param event an EPCIS event, or any object with its `eventTime` and `eventTimeZoneOffset`
|
|
51
|
+
* @returns `{ instant, offset, local }`, or null on invalid input
|
|
52
|
+
*
|
|
53
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T14:30:00Z", eventTimeZoneOffset: "-05:00" }) // { instant: "2024-06-15T14:30:00Z", offset: "-05:00", local: "2024-06-15T09:30:00" }
|
|
54
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T23:30:00Z", eventTimeZoneOffset: "+02:00" }) // { instant: "2024-06-15T23:30:00Z", offset: "+02:00", local: "2024-06-16T01:30:00" } (the local date is the next day)
|
|
55
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T10:00:00+02:00", eventTimeZoneOffset: "+02:00" }) // { instant: "2024-06-15T08:00:00Z", offset: "+02:00", local: "2024-06-15T10:00:00" }
|
|
56
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T10:00:00+02:00", eventTimeZoneOffset: "-05:00" }) // { instant: "2024-06-15T08:00:00Z", offset: "-05:00", local: "2024-06-15T03:00:00" } (the two offsets need not agree)
|
|
57
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T14:30:00.123456789Z", eventTimeZoneOffset: "+05:45" }) // { instant: "2024-06-15T14:30:00.123456789Z", offset: "+05:45", local: "2024-06-15T20:15:00.123456789" }
|
|
58
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T14:30:00Z", eventTimeZoneOffset: "-00:00" }) // { instant: "2024-06-15T14:30:00Z", offset: "+00:00", local: "2024-06-15T14:30:00" }
|
|
59
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T14:30:00Z" }) // null (eventTimeZoneOffset is required)
|
|
60
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T14:30:00Z", eventTimeZoneOffset: "Z" }) // null (a designator, not an offset)
|
|
61
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T14:30:00Z", eventTimeZoneOffset: "+0200" }) // null (no colon)
|
|
62
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T14:30Z", eventTimeZoneOffset: "+02:00" }) // null (seconds are required)
|
|
63
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15 14:30:00Z", eventTimeZoneOffset: "+02:00" }) // null (a space separator)
|
|
64
|
+
* @example parseEpcisEvent({ eventTime: "2024-02-30T14:30:00Z", eventTimeZoneOffset: "+02:00" }) // null (30 February)
|
|
65
|
+
* @example parseEpcisEvent({ eventTime: "2024-06-15T14:30:00.1234567891Z", eventTimeZoneOffset: "+02:00" }) // null (finer than a nanosecond)
|
|
66
|
+
*/
|
|
67
|
+
export function parseEpcisEvent(event) {
|
|
68
|
+
try {
|
|
69
|
+
if (!isObject(event)) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
const { eventTime, eventTimeZoneOffset } = event;
|
|
73
|
+
if (typeof eventTime !== "string" ||
|
|
74
|
+
typeof eventTimeZoneOffset !== "string" ||
|
|
75
|
+
!epcisEventTime.test(eventTime) ||
|
|
76
|
+
!epcisTimeZoneOffset.test(eventTimeZoneOffset)) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
// `epcisEventTime` admits no bracket, so there is no zone whose minute-rounded offset could
|
|
80
|
+
// change the reading and `Temporal.Instant.from` is the whole parse. It also does the two
|
|
81
|
+
// checks the pattern cannot: a day the month does not have, and a fraction past nine digits
|
|
82
|
+
// (Temporal's grammar stops at nanoseconds), both a RangeError.
|
|
83
|
+
const instant = Temporal.Instant.from(eventTime);
|
|
84
|
+
// Temporal reads the offset and writes it back, so `-00:00` comes out as `+00:00` and no
|
|
85
|
+
// offset digit is sliced by hand.
|
|
86
|
+
const offsetNanoseconds = parseUtcOffsetNanoseconds(eventTimeZoneOffset);
|
|
87
|
+
const offset = offsetNanoseconds === null ? null : formatUtcOffset(offsetNanoseconds);
|
|
88
|
+
if (offsetNanoseconds === null || offset === null) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
instant: instant.toString(),
|
|
93
|
+
offset,
|
|
94
|
+
local: wallClockAtOffset(instant, offsetNanoseconds).toString(),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// Never throws (Core Rule 3): a hostile
|
|
99
|
+
// argument is invalid input, not an exception.
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { X12DateFormat } from "../../types/edi.js";
|
|
2
|
+
/**
|
|
3
|
+
* Parse an X12 Date Time Period value that states a calendar date, as an ISO 8601 date.
|
|
4
|
+
*
|
|
5
|
+
* A `DTP` segment carries a format qualifier in `DTP-02` (data element **1250**) and its value
|
|
6
|
+
* in `DTP-03` (data element **1251**); `DTM-05` and `DTM-06` carry the same pair. This function
|
|
7
|
+
* reads the codes whose value is a date. Codes are release 005010, read from
|
|
8
|
+
* [Stedi's X12-licensed dictionary](https://www.stedi.com/edi/x12-005010/element/1250); the X12
|
|
9
|
+
* text itself was not reached.
|
|
10
|
+
*
|
|
11
|
+
* ### Format codes
|
|
12
|
+
* | Code | Mask | The dictionary's definition |
|
|
13
|
+
* |---|---|---|
|
|
14
|
+
* | `D8` | `CCYYMMDD` | "Date Expressed in Format CCYYMMDD" |
|
|
15
|
+
* | `DB` | `MMDDCCYY` | "Date Expressed in Format MMDDCCYY" |
|
|
16
|
+
*
|
|
17
|
+
* - The value must be the eight digits of its code's mask. The same digits can read two ways,
|
|
18
|
+
* so the code decides: `"12112010"` is 11 December 2010 under `DB` and not a date under `D8`.
|
|
19
|
+
* - **`D8` also reads data element 373 (Date)**, the `CCYYMMDD` date element of `AT7`, `G62`
|
|
20
|
+
* and `DTM-02`. To read that date and its time element together, use `parseX12DateAndTime`.
|
|
21
|
+
* - Fields are checked, not clamped: month 13, 31 June and 29 February 2023 return `""`.
|
|
22
|
+
* - A two-digit year (`D6` `YYMMDD`, `TT` `MMDDYY`) is not read: X12 does not say which century
|
|
23
|
+
* it belongs to. Read one with
|
|
24
|
+
* `parseDateWithPattern("240615", "yyMMdd", undefined, { yearWindow: 2000 })`.
|
|
25
|
+
* - Returns `""` for any other code, a code of another kind included (`DT` is read by
|
|
26
|
+
* `parseX12DateTime`), and for a non-string argument.
|
|
27
|
+
*
|
|
28
|
+
* @param value The data element 1251 value (e.g. "20240615")
|
|
29
|
+
* @param format X12 data element 1250 format qualifier
|
|
30
|
+
* @returns the date as `YYYY-MM-DD`, or "" on invalid input
|
|
31
|
+
*
|
|
32
|
+
* @example parseX12Date("20240615", "D8") // "2024-06-15"
|
|
33
|
+
* @example parseX12Date("06152024", "DB") // "2024-06-15"
|
|
34
|
+
* @example parseX12Date("20240615", "DB") // "" (20 is not a month)
|
|
35
|
+
* @example parseX12Date("20230229", "D8") // "" (2023 has no 29 February)
|
|
36
|
+
* @example parseX12Date("240615", "D8") // "" (a two-digit year is not read)
|
|
37
|
+
* @example parseX12Date("202406151430", "DT") // "" (a date-time code: use parseX12DateTime)
|
|
38
|
+
*/
|
|
39
|
+
export declare function parseX12Date(value: string, format: X12DateFormat): string;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { readEdiValue } from "../../internal/ediDateTimeFields.js";
|
|
2
|
+
/**
|
|
3
|
+
* Parse an X12 Date Time Period value that states a calendar date, as an ISO 8601 date.
|
|
4
|
+
*
|
|
5
|
+
* A `DTP` segment carries a format qualifier in `DTP-02` (data element **1250**) and its value
|
|
6
|
+
* in `DTP-03` (data element **1251**); `DTM-05` and `DTM-06` carry the same pair. This function
|
|
7
|
+
* reads the codes whose value is a date. Codes are release 005010, read from
|
|
8
|
+
* [Stedi's X12-licensed dictionary](https://www.stedi.com/edi/x12-005010/element/1250); the X12
|
|
9
|
+
* text itself was not reached.
|
|
10
|
+
*
|
|
11
|
+
* ### Format codes
|
|
12
|
+
* | Code | Mask | The dictionary's definition |
|
|
13
|
+
* |---|---|---|
|
|
14
|
+
* | `D8` | `CCYYMMDD` | "Date Expressed in Format CCYYMMDD" |
|
|
15
|
+
* | `DB` | `MMDDCCYY` | "Date Expressed in Format MMDDCCYY" |
|
|
16
|
+
*
|
|
17
|
+
* - The value must be the eight digits of its code's mask. The same digits can read two ways,
|
|
18
|
+
* so the code decides: `"12112010"` is 11 December 2010 under `DB` and not a date under `D8`.
|
|
19
|
+
* - **`D8` also reads data element 373 (Date)**, the `CCYYMMDD` date element of `AT7`, `G62`
|
|
20
|
+
* and `DTM-02`. To read that date and its time element together, use `parseX12DateAndTime`.
|
|
21
|
+
* - Fields are checked, not clamped: month 13, 31 June and 29 February 2023 return `""`.
|
|
22
|
+
* - A two-digit year (`D6` `YYMMDD`, `TT` `MMDDYY`) is not read: X12 does not say which century
|
|
23
|
+
* it belongs to. Read one with
|
|
24
|
+
* `parseDateWithPattern("240615", "yyMMdd", undefined, { yearWindow: 2000 })`.
|
|
25
|
+
* - Returns `""` for any other code, a code of another kind included (`DT` is read by
|
|
26
|
+
* `parseX12DateTime`), and for a non-string argument.
|
|
27
|
+
*
|
|
28
|
+
* @param value The data element 1251 value (e.g. "20240615")
|
|
29
|
+
* @param format X12 data element 1250 format qualifier
|
|
30
|
+
* @returns the date as `YYYY-MM-DD`, or "" on invalid input
|
|
31
|
+
*
|
|
32
|
+
* @example parseX12Date("20240615", "D8") // "2024-06-15"
|
|
33
|
+
* @example parseX12Date("06152024", "DB") // "2024-06-15"
|
|
34
|
+
* @example parseX12Date("20240615", "DB") // "" (20 is not a month)
|
|
35
|
+
* @example parseX12Date("20230229", "D8") // "" (2023 has no 29 February)
|
|
36
|
+
* @example parseX12Date("240615", "D8") // "" (a two-digit year is not read)
|
|
37
|
+
* @example parseX12Date("202406151430", "DT") // "" (a date-time code: use parseX12DateTime)
|
|
38
|
+
*/
|
|
39
|
+
export function parseX12Date(value, format) {
|
|
40
|
+
try {
|
|
41
|
+
return readEdiValue("x12", "date", format, value);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// Never throws (Core Rule 3): a hostile argument is invalid input, not an exception.
|
|
45
|
+
return "";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read the date and the time of an X12 segment, sent as two elements, as one ISO 8601 local
|
|
3
|
+
* date-time.
|
|
4
|
+
*
|
|
5
|
+
* X12 freight segments carry a moment as separate elements, and this function takes the two as
|
|
6
|
+
* they are transmitted: `AT7-05` and `AT7-06` (in a 214 shipment status), `G62-02` and `G62-04`
|
|
7
|
+
* (a 204 load tender) and `DTM-02` and `DTM-03`. Definitions are release 005010, read from
|
|
8
|
+
* [Stedi's X12-licensed dictionary](https://www.stedi.com/edi/x12-005010/segment/DTM); the X12
|
|
9
|
+
* text itself was not reached.
|
|
10
|
+
*
|
|
11
|
+
* ### The two elements
|
|
12
|
+
* | Element | Name | The dictionary's definition |
|
|
13
|
+
* |---|---|---|
|
|
14
|
+
* | [373](https://www.stedi.com/edi/x12-005010/element/373) | Date | "Date expressed as CCYYMMDD where CC represents the first two digits of the calendar year" |
|
|
15
|
+
* | [337](https://www.stedi.com/edi/x12-005010/element/337) | Time | "Time expressed in 24-hour clock time as follows: HHMM, or HHMMSS, or HHMMSSD, or HHMMSSDD" |
|
|
16
|
+
*
|
|
17
|
+
* - **The result is local, never UTC.** It has no `Z` and no offset. `AT7` says what a blank
|
|
18
|
+
* time code means: "If AT707 is not present then AT706 represents local time of the status".
|
|
19
|
+
* Reading the value as UTC is the most common EDI timestamp bug.
|
|
20
|
+
* - **The time code beside them (data element 623) says where the clock was.** For a code that
|
|
21
|
+
* states an offset, resolve the result at that offset:
|
|
22
|
+
* `resolveLocal(parseX12DateAndTime("20240615", "1430"), x12TimeCodeOffset("20"))` is
|
|
23
|
+
* `"2024-06-15T19:30:00Z"`. For a code that names a zone (`x12TimeCodeZone`), pass the result
|
|
24
|
+
* and the IANA zone you map the name to, to `resolveLocal`.
|
|
25
|
+
* - **Both elements are required.** A missing or empty date or time returns `""`: read a date
|
|
26
|
+
* alone with `parseX12Date(value, "D8")` and a time alone with `parseX12Time`.
|
|
27
|
+
* - The time is one of the four element 337 forms, 4, 6, 7 or 8 digits. Seconds are always
|
|
28
|
+
* written, `00` for `HHMM`. Tenths and hundredths become the fraction of the second exactly:
|
|
29
|
+
* `14300012` is `14:30:00.12`. A zero fraction is not written.
|
|
30
|
+
* - **To write the two elements back**, write the date with `formatX12Date(date, "D8")` and the
|
|
31
|
+
* time with `formatX12TimeElement`, naming the element 337 form by its mask:
|
|
32
|
+
* `formatX12TimeElement("14:30:00.12", "HHMMSSDD")` is `14300012`.
|
|
33
|
+
* - Fields are checked, not clamped: 29 February 2023, 31 June, hour 24, minute or second 60
|
|
34
|
+
* and a time of 5 or 9 digits return `""`.
|
|
35
|
+
* - The date has a four-digit year. Before release 004010, element 373 was `YYMMDD`: read such
|
|
36
|
+
* a date with `parseDateWithPattern("240615", "yyMMdd", undefined, { yearWindow: 2000 })`.
|
|
37
|
+
* - Returns `""` for a non-string argument.
|
|
38
|
+
*
|
|
39
|
+
* @param date The data element 373 date as transmitted, `CCYYMMDD` (e.g. "20240615")
|
|
40
|
+
* @param time The data element 337 time as transmitted (e.g. "1430")
|
|
41
|
+
* @returns the local date-time as `YYYY-MM-DDTHH:MM:SS`, with a fraction when the time has one, or "" on invalid input
|
|
42
|
+
*
|
|
43
|
+
* @example parseX12DateAndTime("20240615", "1430") // "2024-06-15T14:30:00"
|
|
44
|
+
* @example parseX12DateAndTime("20240615", "143045") // "2024-06-15T14:30:45"
|
|
45
|
+
* @example parseX12DateAndTime("20240615", "14300012") // "2024-06-15T14:30:00.12" (hundredths of a second)
|
|
46
|
+
* @example parseX12DateAndTime("20240615", "") // "" (both elements are required)
|
|
47
|
+
* @example parseX12DateAndTime("", "1430") // "" (both elements are required)
|
|
48
|
+
* @example parseX12DateAndTime("20230229", "1430") // "" (2023 has no 29 February)
|
|
49
|
+
* @example parseX12DateAndTime("20240615", "2430") // "" (hour 24)
|
|
50
|
+
* @example parseX12DateAndTime("240615", "1430") // "" (the date element has a four-digit year)
|
|
51
|
+
*/
|
|
52
|
+
export declare function parseX12DateAndTime(date: string, time: string): string;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { readX12DateAndTime } from "../../internal/ediDateTimeFields.js";
|
|
2
|
+
/**
|
|
3
|
+
* Read the date and the time of an X12 segment, sent as two elements, as one ISO 8601 local
|
|
4
|
+
* date-time.
|
|
5
|
+
*
|
|
6
|
+
* X12 freight segments carry a moment as separate elements, and this function takes the two as
|
|
7
|
+
* they are transmitted: `AT7-05` and `AT7-06` (in a 214 shipment status), `G62-02` and `G62-04`
|
|
8
|
+
* (a 204 load tender) and `DTM-02` and `DTM-03`. Definitions are release 005010, read from
|
|
9
|
+
* [Stedi's X12-licensed dictionary](https://www.stedi.com/edi/x12-005010/segment/DTM); the X12
|
|
10
|
+
* text itself was not reached.
|
|
11
|
+
*
|
|
12
|
+
* ### The two elements
|
|
13
|
+
* | Element | Name | The dictionary's definition |
|
|
14
|
+
* |---|---|---|
|
|
15
|
+
* | [373](https://www.stedi.com/edi/x12-005010/element/373) | Date | "Date expressed as CCYYMMDD where CC represents the first two digits of the calendar year" |
|
|
16
|
+
* | [337](https://www.stedi.com/edi/x12-005010/element/337) | Time | "Time expressed in 24-hour clock time as follows: HHMM, or HHMMSS, or HHMMSSD, or HHMMSSDD" |
|
|
17
|
+
*
|
|
18
|
+
* - **The result is local, never UTC.** It has no `Z` and no offset. `AT7` says what a blank
|
|
19
|
+
* time code means: "If AT707 is not present then AT706 represents local time of the status".
|
|
20
|
+
* Reading the value as UTC is the most common EDI timestamp bug.
|
|
21
|
+
* - **The time code beside them (data element 623) says where the clock was.** For a code that
|
|
22
|
+
* states an offset, resolve the result at that offset:
|
|
23
|
+
* `resolveLocal(parseX12DateAndTime("20240615", "1430"), x12TimeCodeOffset("20"))` is
|
|
24
|
+
* `"2024-06-15T19:30:00Z"`. For a code that names a zone (`x12TimeCodeZone`), pass the result
|
|
25
|
+
* and the IANA zone you map the name to, to `resolveLocal`.
|
|
26
|
+
* - **Both elements are required.** A missing or empty date or time returns `""`: read a date
|
|
27
|
+
* alone with `parseX12Date(value, "D8")` and a time alone with `parseX12Time`.
|
|
28
|
+
* - The time is one of the four element 337 forms, 4, 6, 7 or 8 digits. Seconds are always
|
|
29
|
+
* written, `00` for `HHMM`. Tenths and hundredths become the fraction of the second exactly:
|
|
30
|
+
* `14300012` is `14:30:00.12`. A zero fraction is not written.
|
|
31
|
+
* - **To write the two elements back**, write the date with `formatX12Date(date, "D8")` and the
|
|
32
|
+
* time with `formatX12TimeElement`, naming the element 337 form by its mask:
|
|
33
|
+
* `formatX12TimeElement("14:30:00.12", "HHMMSSDD")` is `14300012`.
|
|
34
|
+
* - Fields are checked, not clamped: 29 February 2023, 31 June, hour 24, minute or second 60
|
|
35
|
+
* and a time of 5 or 9 digits return `""`.
|
|
36
|
+
* - The date has a four-digit year. Before release 004010, element 373 was `YYMMDD`: read such
|
|
37
|
+
* a date with `parseDateWithPattern("240615", "yyMMdd", undefined, { yearWindow: 2000 })`.
|
|
38
|
+
* - Returns `""` for a non-string argument.
|
|
39
|
+
*
|
|
40
|
+
* @param date The data element 373 date as transmitted, `CCYYMMDD` (e.g. "20240615")
|
|
41
|
+
* @param time The data element 337 time as transmitted (e.g. "1430")
|
|
42
|
+
* @returns the local date-time as `YYYY-MM-DDTHH:MM:SS`, with a fraction when the time has one, or "" on invalid input
|
|
43
|
+
*
|
|
44
|
+
* @example parseX12DateAndTime("20240615", "1430") // "2024-06-15T14:30:00"
|
|
45
|
+
* @example parseX12DateAndTime("20240615", "143045") // "2024-06-15T14:30:45"
|
|
46
|
+
* @example parseX12DateAndTime("20240615", "14300012") // "2024-06-15T14:30:00.12" (hundredths of a second)
|
|
47
|
+
* @example parseX12DateAndTime("20240615", "") // "" (both elements are required)
|
|
48
|
+
* @example parseX12DateAndTime("", "1430") // "" (both elements are required)
|
|
49
|
+
* @example parseX12DateAndTime("20230229", "1430") // "" (2023 has no 29 February)
|
|
50
|
+
* @example parseX12DateAndTime("20240615", "2430") // "" (hour 24)
|
|
51
|
+
* @example parseX12DateAndTime("240615", "1430") // "" (the date element has a four-digit year)
|
|
52
|
+
*/
|
|
53
|
+
export function parseX12DateAndTime(date, time) {
|
|
54
|
+
try {
|
|
55
|
+
return readX12DateAndTime(date, time);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// Never throws (Core Rule 3): a hostile argument is invalid input, not an exception.
|
|
59
|
+
return "";
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { EdiDatePeriod, X12DateRangeFormat } from "../../types/edi.js";
|
|
2
|
+
/**
|
|
3
|
+
* Parse an X12 Date Time Period value that states a range between two calendar dates, as its
|
|
4
|
+
* start and end.
|
|
5
|
+
*
|
|
6
|
+
* A `DTP` segment carries a format qualifier in `DTP-02` (data element **1250**) and its value
|
|
7
|
+
* in `DTP-03` (data element **1251**); `DTM-05` and `DTM-06` carry the same pair. Codes are
|
|
8
|
+
* release 005010, read from
|
|
9
|
+
* [Stedi's X12-licensed dictionary](https://www.stedi.com/edi/x12-005010/element/1250); the X12
|
|
10
|
+
* text itself was not reached.
|
|
11
|
+
*
|
|
12
|
+
* ### Format codes
|
|
13
|
+
* | Code | Mask | The dictionary's definition |
|
|
14
|
+
* |---|---|---|
|
|
15
|
+
* | `RD8` | `CCYYMMDD-CCYYMMDD` | "Range of Dates Expressed in Format CCYYMMDD-CCYYMMDD" |
|
|
16
|
+
* | `RD` | `MMDDCCYY-MMDDCCYY` | "Range of Dates Expressed in Format MMDDCCYY-MMDDCCYY" |
|
|
17
|
+
*
|
|
18
|
+
* - **A range is transmitted with exactly one hyphen.** Each definition gives the format with
|
|
19
|
+
* its hyphen: `"20240615-20240620"` reads, and `"2024061520240620"` returns `null`.
|
|
20
|
+
* - **`start` and `end` are the two dates as transmitted**, each `YYYY-MM-DD`. X12 does not say
|
|
21
|
+
* here whether the end date is inside the range: that is the segment's to define, so no day
|
|
22
|
+
* is added or removed. Pass the pair to the plain interval functions as `(start, end)`, for
|
|
23
|
+
* example `intervalLengthDate(range.start, range.end, "days")`; they leave `end` outside the
|
|
24
|
+
* interval.
|
|
25
|
+
* - **An end before its start returns `null`**: a reversed range names no span of time. An end
|
|
26
|
+
* equal to its start is a valid range.
|
|
27
|
+
* - Fields are checked, not clamped: month 13, 31 June and 29 February 2023 return `null`.
|
|
28
|
+
* - A two-digit year (`RD6`, `YYMMDD-YYMMDD`) is not read. Split such a value at its hyphen and
|
|
29
|
+
* read each half with `parseDateWithPattern`, a `yy` pattern and its `yearWindow` option.
|
|
30
|
+
* - Returns `null` for any other code, a code of another kind included (`RDT` is read by
|
|
31
|
+
* `parseX12DateTimeRange`), and for a non-string argument.
|
|
32
|
+
*
|
|
33
|
+
* @param value The data element 1251 value (e.g. "20240615-20240620")
|
|
34
|
+
* @param format X12 data element 1250 format qualifier
|
|
35
|
+
* @returns `{ start, end }`, two ISO 8601 dates, or null on invalid input
|
|
36
|
+
*
|
|
37
|
+
* @example parseX12DateRange("20240615-20240620", "RD8") // { start: "2024-06-15", end: "2024-06-20" }
|
|
38
|
+
* @example parseX12DateRange("06152024-06202024", "RD") // { start: "2024-06-15", end: "2024-06-20" }
|
|
39
|
+
* @example parseX12DateRange("2024061520240620", "RD8") // null (a range is transmitted with its hyphen)
|
|
40
|
+
* @example parseX12DateRange("20240620-20240615", "RD8") // null (the end precedes the start)
|
|
41
|
+
* @example parseX12DateRange("20230229-20240620", "RD8") // null (2023 has no 29 February)
|
|
42
|
+
* @example parseX12DateRange("20240615", "D8") // null (a date code: use parseX12Date)
|
|
43
|
+
*/
|
|
44
|
+
export declare function parseX12DateRange(value: string, format: X12DateRangeFormat): EdiDatePeriod | null;
|