@cdx-ui/formatters 0.0.1-beta.132
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 +108 -0
- package/lib/commonjs/dates/calendar/formatCalendarMonthYear.js +28 -0
- package/lib/commonjs/dates/calendar/formatCalendarMonthYear.js.map +1 -0
- package/lib/commonjs/dates/calendar/formatDateTimeListDateRow.js +40 -0
- package/lib/commonjs/dates/calendar/formatDateTimeListDateRow.js.map +1 -0
- package/lib/commonjs/dates/calendar/formatMonthCalendarMonth.js +28 -0
- package/lib/commonjs/dates/calendar/formatMonthCalendarMonth.js.map +1 -0
- package/lib/commonjs/dates/calendar/formatMonthCalendarYear.js +16 -0
- package/lib/commonjs/dates/calendar/formatMonthCalendarYear.js.map +1 -0
- package/lib/commonjs/dates/calendar/getCalendarWeekdayLabels.js +23 -0
- package/lib/commonjs/dates/calendar/getCalendarWeekdayLabels.js.map +1 -0
- package/lib/commonjs/dates/datetime/clampDateTimeId.js +27 -0
- package/lib/commonjs/dates/datetime/clampDateTimeId.js.map +1 -0
- package/lib/commonjs/dates/datetime/compareDateTimeIds.js +28 -0
- package/lib/commonjs/dates/datetime/compareDateTimeIds.js.map +1 -0
- package/lib/commonjs/dates/datetime/dateTimeId.js +38 -0
- package/lib/commonjs/dates/datetime/dateTimeId.js.map +1 -0
- package/lib/commonjs/dates/datetime/formatDateTimeId.js +27 -0
- package/lib/commonjs/dates/datetime/formatDateTimeId.js.map +1 -0
- package/lib/commonjs/dates/datetime/formatDateTimeListHour.js +21 -0
- package/lib/commonjs/dates/datetime/formatDateTimeListHour.js.map +1 -0
- package/lib/commonjs/dates/datetime/formatDateTimeListMinute.js +16 -0
- package/lib/commonjs/dates/datetime/formatDateTimeListMinute.js.map +1 -0
- package/lib/commonjs/dates/datetime/formatDateTimeListPeriod.js +17 -0
- package/lib/commonjs/dates/datetime/formatDateTimeListPeriod.js.map +1 -0
- package/lib/commonjs/dates/datetime/isLocaleHour12.js +30 -0
- package/lib/commonjs/dates/datetime/isLocaleHour12.js.map +1 -0
- package/lib/commonjs/dates/datetime/isValidDateTimeId.js +23 -0
- package/lib/commonjs/dates/datetime/isValidDateTimeId.js.map +1 -0
- package/lib/commonjs/dates/datetime/nowDateTimeId.js +57 -0
- package/lib/commonjs/dates/datetime/nowDateTimeId.js.map +1 -0
- package/lib/commonjs/dates/datetime/parseDateTimeId.js +29 -0
- package/lib/commonjs/dates/datetime/parseDateTimeId.js.map +1 -0
- package/lib/commonjs/dates/display/formatDateForDisplay.js +28 -0
- package/lib/commonjs/dates/display/formatDateForDisplay.js.map +1 -0
- package/lib/commonjs/dates/display/formatDateRangeForDisplay.js +25 -0
- package/lib/commonjs/dates/display/formatDateRangeForDisplay.js.map +1 -0
- package/lib/commonjs/dates/display/formatDateTimeForDisplay.js +34 -0
- package/lib/commonjs/dates/display/formatDateTimeForDisplay.js.map +1 -0
- package/lib/commonjs/dates/display/formatMonthForDisplay.js +33 -0
- package/lib/commonjs/dates/display/formatMonthForDisplay.js.map +1 -0
- package/lib/commonjs/dates/index.js +367 -0
- package/lib/commonjs/dates/index.js.map +1 -0
- package/lib/commonjs/dates/internal/brand.js +19 -0
- package/lib/commonjs/dates/internal/brand.js.map +1 -0
- package/lib/commonjs/dates/internal/calendarHelpers.js +22 -0
- package/lib/commonjs/dates/internal/calendarHelpers.js.map +1 -0
- package/lib/commonjs/dates/internal/clampHelpers.js +20 -0
- package/lib/commonjs/dates/internal/clampHelpers.js.map +1 -0
- package/lib/commonjs/dates/internal/dateIdToNativeDate.js +20 -0
- package/lib/commonjs/dates/internal/dateIdToNativeDate.js.map +1 -0
- package/lib/commonjs/dates/internal/intlCache.js +52 -0
- package/lib/commonjs/dates/internal/intlCache.js.map +1 -0
- package/lib/commonjs/dates/internal/intlCopy.js +72 -0
- package/lib/commonjs/dates/internal/intlCopy.js.map +1 -0
- package/lib/commonjs/dates/internal/segmentBuilders.js +98 -0
- package/lib/commonjs/dates/internal/segmentBuilders.js.map +1 -0
- package/lib/commonjs/dates/labels/dateComponentLabels.js +57 -0
- package/lib/commonjs/dates/labels/dateComponentLabels.js.map +1 -0
- package/lib/commonjs/dates/ranges/compareDateIds.js +26 -0
- package/lib/commonjs/dates/ranges/compareDateIds.js.map +1 -0
- package/lib/commonjs/dates/ranges/compareMonthIds.js +31 -0
- package/lib/commonjs/dates/ranges/compareMonthIds.js.map +1 -0
- package/lib/commonjs/dates/ranges/dateRangeAroundDay.js +25 -0
- package/lib/commonjs/dates/ranges/dateRangeAroundDay.js.map +1 -0
- package/lib/commonjs/dates/ranges/dateRangeFromLastNDays.js +28 -0
- package/lib/commonjs/dates/ranges/dateRangeFromLastNDays.js.map +1 -0
- package/lib/commonjs/dates/ranges/eachDateIdInRange.js +29 -0
- package/lib/commonjs/dates/ranges/eachDateIdInRange.js.map +1 -0
- package/lib/commonjs/dates/ranges/normalizeDateRange.js +23 -0
- package/lib/commonjs/dates/ranges/normalizeDateRange.js.map +1 -0
- package/lib/commonjs/dates/segments/applyDateSegmentChange.js +77 -0
- package/lib/commonjs/dates/segments/applyDateSegmentChange.js.map +1 -0
- package/lib/commonjs/dates/segments/formatDateSegment.js +19 -0
- package/lib/commonjs/dates/segments/formatDateSegment.js.map +1 -0
- package/lib/commonjs/dates/segments/getDateFieldSegments.js +44 -0
- package/lib/commonjs/dates/segments/getDateFieldSegments.js.map +1 -0
- package/lib/commonjs/dates/segments/getDateTimeFieldSegments.js +150 -0
- package/lib/commonjs/dates/segments/getDateTimeFieldSegments.js.map +1 -0
- package/lib/commonjs/dates/segments/getDateTimeSegmentVisibility.js +15 -0
- package/lib/commonjs/dates/segments/getDateTimeSegmentVisibility.js.map +1 -0
- package/lib/commonjs/dates/segments/getEmptyDateSegmentText.js +17 -0
- package/lib/commonjs/dates/segments/getEmptyDateSegmentText.js.map +1 -0
- package/lib/commonjs/dates/segments/parseDateSegment.js +26 -0
- package/lib/commonjs/dates/segments/parseDateSegment.js.map +1 -0
- package/lib/commonjs/dates/types.js +2 -0
- package/lib/commonjs/dates/types.js.map +1 -0
- package/lib/commonjs/dates/wire/clampDateParts.js +26 -0
- package/lib/commonjs/dates/wire/clampDateParts.js.map +1 -0
- package/lib/commonjs/dates/wire/clampMonthParts.js +23 -0
- package/lib/commonjs/dates/wire/clampMonthParts.js.map +1 -0
- package/lib/commonjs/dates/wire/dateId.js +50 -0
- package/lib/commonjs/dates/wire/dateId.js.map +1 -0
- package/lib/commonjs/dates/wire/formatDateId.js +25 -0
- package/lib/commonjs/dates/wire/formatDateId.js.map +1 -0
- package/lib/commonjs/dates/wire/formatMonthId.js +21 -0
- package/lib/commonjs/dates/wire/formatMonthId.js.map +1 -0
- package/lib/commonjs/dates/wire/isValidDateId.js +27 -0
- package/lib/commonjs/dates/wire/isValidDateId.js.map +1 -0
- package/lib/commonjs/dates/wire/isValidDateParts.js +18 -0
- package/lib/commonjs/dates/wire/isValidDateParts.js.map +1 -0
- package/lib/commonjs/dates/wire/isValidMonthId.js +27 -0
- package/lib/commonjs/dates/wire/isValidMonthId.js.map +1 -0
- package/lib/commonjs/dates/wire/isValidMonthParts.js +16 -0
- package/lib/commonjs/dates/wire/isValidMonthParts.js.map +1 -0
- package/lib/commonjs/dates/wire/monthId.js +47 -0
- package/lib/commonjs/dates/wire/monthId.js.map +1 -0
- package/lib/commonjs/dates/wire/parseDateId.js +29 -0
- package/lib/commonjs/dates/wire/parseDateId.js.map +1 -0
- package/lib/commonjs/dates/wire/parseMonthId.js +28 -0
- package/lib/commonjs/dates/wire/parseMonthId.js.map +1 -0
- package/lib/commonjs/dates/wire/toMonthId.js +22 -0
- package/lib/commonjs/dates/wire/toMonthId.js.map +1 -0
- package/lib/commonjs/dates/wire/todayDateId.js +17 -0
- package/lib/commonjs/dates/wire/todayDateId.js.map +1 -0
- package/lib/commonjs/dates/wire/todayMonthId.js +17 -0
- package/lib/commonjs/dates/wire/todayMonthId.js.map +1 -0
- package/lib/commonjs/formatNumber.js +50 -0
- package/lib/commonjs/formatNumber.js.map +1 -0
- package/lib/commonjs/index.js +326 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/types.js +2 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/commonjs/utils.js +33 -0
- package/lib/commonjs/utils.js.map +1 -0
- package/lib/module/dates/calendar/formatCalendarMonthYear.js +24 -0
- package/lib/module/dates/calendar/formatCalendarMonthYear.js.map +1 -0
- package/lib/module/dates/calendar/formatDateTimeListDateRow.js +36 -0
- package/lib/module/dates/calendar/formatDateTimeListDateRow.js.map +1 -0
- package/lib/module/dates/calendar/formatMonthCalendarMonth.js +24 -0
- package/lib/module/dates/calendar/formatMonthCalendarMonth.js.map +1 -0
- package/lib/module/dates/calendar/formatMonthCalendarYear.js +12 -0
- package/lib/module/dates/calendar/formatMonthCalendarYear.js.map +1 -0
- package/lib/module/dates/calendar/getCalendarWeekdayLabels.js +19 -0
- package/lib/module/dates/calendar/getCalendarWeekdayLabels.js.map +1 -0
- package/lib/module/dates/datetime/clampDateTimeId.js +24 -0
- package/lib/module/dates/datetime/clampDateTimeId.js.map +1 -0
- package/lib/module/dates/datetime/compareDateTimeIds.js +24 -0
- package/lib/module/dates/datetime/compareDateTimeIds.js.map +1 -0
- package/lib/module/dates/datetime/dateTimeId.js +35 -0
- package/lib/module/dates/datetime/dateTimeId.js.map +1 -0
- package/lib/module/dates/datetime/formatDateTimeId.js +23 -0
- package/lib/module/dates/datetime/formatDateTimeId.js.map +1 -0
- package/lib/module/dates/datetime/formatDateTimeListHour.js +17 -0
- package/lib/module/dates/datetime/formatDateTimeListHour.js.map +1 -0
- package/lib/module/dates/datetime/formatDateTimeListMinute.js +12 -0
- package/lib/module/dates/datetime/formatDateTimeListMinute.js.map +1 -0
- package/lib/module/dates/datetime/formatDateTimeListPeriod.js +13 -0
- package/lib/module/dates/datetime/formatDateTimeListPeriod.js.map +1 -0
- package/lib/module/dates/datetime/isLocaleHour12.js +26 -0
- package/lib/module/dates/datetime/isLocaleHour12.js.map +1 -0
- package/lib/module/dates/datetime/isValidDateTimeId.js +19 -0
- package/lib/module/dates/datetime/isValidDateTimeId.js.map +1 -0
- package/lib/module/dates/datetime/nowDateTimeId.js +54 -0
- package/lib/module/dates/datetime/nowDateTimeId.js.map +1 -0
- package/lib/module/dates/datetime/parseDateTimeId.js +26 -0
- package/lib/module/dates/datetime/parseDateTimeId.js.map +1 -0
- package/lib/module/dates/display/formatDateForDisplay.js +24 -0
- package/lib/module/dates/display/formatDateForDisplay.js.map +1 -0
- package/lib/module/dates/display/formatDateRangeForDisplay.js +22 -0
- package/lib/module/dates/display/formatDateRangeForDisplay.js.map +1 -0
- package/lib/module/dates/display/formatDateTimeForDisplay.js +30 -0
- package/lib/module/dates/display/formatDateTimeForDisplay.js.map +1 -0
- package/lib/module/dates/display/formatMonthForDisplay.js +29 -0
- package/lib/module/dates/display/formatMonthForDisplay.js.map +1 -0
- package/lib/module/dates/index.js +59 -0
- package/lib/module/dates/index.js.map +1 -0
- package/lib/module/dates/internal/brand.js +12 -0
- package/lib/module/dates/internal/brand.js.map +1 -0
- package/lib/module/dates/internal/calendarHelpers.js +19 -0
- package/lib/module/dates/internal/calendarHelpers.js.map +1 -0
- package/lib/module/dates/internal/clampHelpers.js +14 -0
- package/lib/module/dates/internal/clampHelpers.js.map +1 -0
- package/lib/module/dates/internal/dateIdToNativeDate.js +16 -0
- package/lib/module/dates/internal/dateIdToNativeDate.js.map +1 -0
- package/lib/module/dates/internal/intlCache.js +47 -0
- package/lib/module/dates/internal/intlCache.js.map +1 -0
- package/lib/module/dates/internal/intlCopy.js +66 -0
- package/lib/module/dates/internal/intlCopy.js.map +1 -0
- package/lib/module/dates/internal/segmentBuilders.js +91 -0
- package/lib/module/dates/internal/segmentBuilders.js.map +1 -0
- package/lib/module/dates/labels/dateComponentLabels.js +50 -0
- package/lib/module/dates/labels/dateComponentLabels.js.map +1 -0
- package/lib/module/dates/ranges/compareDateIds.js +22 -0
- package/lib/module/dates/ranges/compareDateIds.js.map +1 -0
- package/lib/module/dates/ranges/compareMonthIds.js +27 -0
- package/lib/module/dates/ranges/compareMonthIds.js.map +1 -0
- package/lib/module/dates/ranges/dateRangeAroundDay.js +21 -0
- package/lib/module/dates/ranges/dateRangeAroundDay.js.map +1 -0
- package/lib/module/dates/ranges/dateRangeFromLastNDays.js +24 -0
- package/lib/module/dates/ranges/dateRangeFromLastNDays.js.map +1 -0
- package/lib/module/dates/ranges/eachDateIdInRange.js +26 -0
- package/lib/module/dates/ranges/eachDateIdInRange.js.map +1 -0
- package/lib/module/dates/ranges/normalizeDateRange.js +20 -0
- package/lib/module/dates/ranges/normalizeDateRange.js.map +1 -0
- package/lib/module/dates/segments/applyDateSegmentChange.js +73 -0
- package/lib/module/dates/segments/applyDateSegmentChange.js.map +1 -0
- package/lib/module/dates/segments/formatDateSegment.js +15 -0
- package/lib/module/dates/segments/formatDateSegment.js.map +1 -0
- package/lib/module/dates/segments/getDateFieldSegments.js +40 -0
- package/lib/module/dates/segments/getDateFieldSegments.js.map +1 -0
- package/lib/module/dates/segments/getDateTimeFieldSegments.js +147 -0
- package/lib/module/dates/segments/getDateTimeFieldSegments.js.map +1 -0
- package/lib/module/dates/segments/getDateTimeSegmentVisibility.js +11 -0
- package/lib/module/dates/segments/getDateTimeSegmentVisibility.js.map +1 -0
- package/lib/module/dates/segments/getEmptyDateSegmentText.js +13 -0
- package/lib/module/dates/segments/getEmptyDateSegmentText.js.map +1 -0
- package/lib/module/dates/segments/parseDateSegment.js +22 -0
- package/lib/module/dates/segments/parseDateSegment.js.map +1 -0
- package/lib/module/dates/types.js +2 -0
- package/lib/module/dates/types.js.map +1 -0
- package/lib/module/dates/wire/clampDateParts.js +22 -0
- package/lib/module/dates/wire/clampDateParts.js.map +1 -0
- package/lib/module/dates/wire/clampMonthParts.js +19 -0
- package/lib/module/dates/wire/clampMonthParts.js.map +1 -0
- package/lib/module/dates/wire/dateId.js +47 -0
- package/lib/module/dates/wire/dateId.js.map +1 -0
- package/lib/module/dates/wire/formatDateId.js +22 -0
- package/lib/module/dates/wire/formatDateId.js.map +1 -0
- package/lib/module/dates/wire/formatMonthId.js +17 -0
- package/lib/module/dates/wire/formatMonthId.js.map +1 -0
- package/lib/module/dates/wire/isValidDateId.js +23 -0
- package/lib/module/dates/wire/isValidDateId.js.map +1 -0
- package/lib/module/dates/wire/isValidDateParts.js +14 -0
- package/lib/module/dates/wire/isValidDateParts.js.map +1 -0
- package/lib/module/dates/wire/isValidMonthId.js +23 -0
- package/lib/module/dates/wire/isValidMonthId.js.map +1 -0
- package/lib/module/dates/wire/isValidMonthParts.js +12 -0
- package/lib/module/dates/wire/isValidMonthParts.js.map +1 -0
- package/lib/module/dates/wire/monthId.js +44 -0
- package/lib/module/dates/wire/monthId.js.map +1 -0
- package/lib/module/dates/wire/parseDateId.js +26 -0
- package/lib/module/dates/wire/parseDateId.js.map +1 -0
- package/lib/module/dates/wire/parseMonthId.js +25 -0
- package/lib/module/dates/wire/parseMonthId.js.map +1 -0
- package/lib/module/dates/wire/toMonthId.js +18 -0
- package/lib/module/dates/wire/toMonthId.js.map +1 -0
- package/lib/module/dates/wire/todayDateId.js +13 -0
- package/lib/module/dates/wire/todayDateId.js.map +1 -0
- package/lib/module/dates/wire/todayMonthId.js +13 -0
- package/lib/module/dates/wire/todayMonthId.js.map +1 -0
- package/lib/module/formatNumber.js +46 -0
- package/lib/module/formatNumber.js.map +1 -0
- package/lib/module/index.js +17 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/utils.js +29 -0
- package/lib/module/utils.js.map +1 -0
- package/lib/typescript/dates/calendar/formatCalendarMonthYear.d.ts +12 -0
- package/lib/typescript/dates/calendar/formatCalendarMonthYear.d.ts.map +1 -0
- package/lib/typescript/dates/calendar/formatDateTimeListDateRow.d.ts +13 -0
- package/lib/typescript/dates/calendar/formatDateTimeListDateRow.d.ts.map +1 -0
- package/lib/typescript/dates/calendar/formatMonthCalendarMonth.d.ts +13 -0
- package/lib/typescript/dates/calendar/formatMonthCalendarMonth.d.ts.map +1 -0
- package/lib/typescript/dates/calendar/formatMonthCalendarYear.d.ts +8 -0
- package/lib/typescript/dates/calendar/formatMonthCalendarYear.d.ts.map +1 -0
- package/lib/typescript/dates/calendar/getCalendarWeekdayLabels.d.ts +12 -0
- package/lib/typescript/dates/calendar/getCalendarWeekdayLabels.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/clampDateTimeId.d.ts +16 -0
- package/lib/typescript/dates/datetime/clampDateTimeId.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/compareDateTimeIds.d.ts +13 -0
- package/lib/typescript/dates/datetime/compareDateTimeIds.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/dateTimeId.d.ts +18 -0
- package/lib/typescript/dates/datetime/dateTimeId.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/formatDateTimeId.d.ts +12 -0
- package/lib/typescript/dates/datetime/formatDateTimeId.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/formatDateTimeListHour.d.ts +11 -0
- package/lib/typescript/dates/datetime/formatDateTimeListHour.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/formatDateTimeListMinute.d.ts +8 -0
- package/lib/typescript/dates/datetime/formatDateTimeListMinute.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/formatDateTimeListPeriod.d.ts +9 -0
- package/lib/typescript/dates/datetime/formatDateTimeListPeriod.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/isLocaleHour12.d.ts +12 -0
- package/lib/typescript/dates/datetime/isLocaleHour12.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/isValidDateTimeId.d.ts +9 -0
- package/lib/typescript/dates/datetime/isValidDateTimeId.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/nowDateTimeId.d.ts +14 -0
- package/lib/typescript/dates/datetime/nowDateTimeId.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/parseDateTimeId.d.ts +9 -0
- package/lib/typescript/dates/datetime/parseDateTimeId.d.ts.map +1 -0
- package/lib/typescript/dates/display/formatDateForDisplay.d.ts +13 -0
- package/lib/typescript/dates/display/formatDateForDisplay.d.ts.map +1 -0
- package/lib/typescript/dates/display/formatDateRangeForDisplay.d.ts +16 -0
- package/lib/typescript/dates/display/formatDateRangeForDisplay.d.ts.map +1 -0
- package/lib/typescript/dates/display/formatDateTimeForDisplay.d.ts +13 -0
- package/lib/typescript/dates/display/formatDateTimeForDisplay.d.ts.map +1 -0
- package/lib/typescript/dates/display/formatMonthForDisplay.d.ts +13 -0
- package/lib/typescript/dates/display/formatMonthForDisplay.d.ts.map +1 -0
- package/lib/typescript/dates/index.d.ts +58 -0
- package/lib/typescript/dates/index.d.ts.map +1 -0
- package/lib/typescript/dates/internal/brand.d.ts +11 -0
- package/lib/typescript/dates/internal/brand.d.ts.map +1 -0
- package/lib/typescript/dates/internal/calendarHelpers.d.ts +8 -0
- package/lib/typescript/dates/internal/calendarHelpers.d.ts.map +1 -0
- package/lib/typescript/dates/internal/clampHelpers.d.ts +5 -0
- package/lib/typescript/dates/internal/clampHelpers.d.ts.map +1 -0
- package/lib/typescript/dates/internal/dateIdToNativeDate.d.ts +12 -0
- package/lib/typescript/dates/internal/dateIdToNativeDate.d.ts.map +1 -0
- package/lib/typescript/dates/internal/intlCache.d.ts +12 -0
- package/lib/typescript/dates/internal/intlCache.d.ts.map +1 -0
- package/lib/typescript/dates/internal/intlCopy.d.ts +10 -0
- package/lib/typescript/dates/internal/intlCopy.d.ts.map +1 -0
- package/lib/typescript/dates/internal/segmentBuilders.d.ts +12 -0
- package/lib/typescript/dates/internal/segmentBuilders.d.ts.map +1 -0
- package/lib/typescript/dates/labels/dateComponentLabels.d.ts +31 -0
- package/lib/typescript/dates/labels/dateComponentLabels.d.ts.map +1 -0
- package/lib/typescript/dates/ranges/compareDateIds.d.ts +10 -0
- package/lib/typescript/dates/ranges/compareDateIds.d.ts.map +1 -0
- package/lib/typescript/dates/ranges/compareMonthIds.d.ts +10 -0
- package/lib/typescript/dates/ranges/compareMonthIds.d.ts.map +1 -0
- package/lib/typescript/dates/ranges/dateRangeAroundDay.d.ts +14 -0
- package/lib/typescript/dates/ranges/dateRangeAroundDay.d.ts.map +1 -0
- package/lib/typescript/dates/ranges/dateRangeFromLastNDays.d.ts +16 -0
- package/lib/typescript/dates/ranges/dateRangeFromLastNDays.d.ts.map +1 -0
- package/lib/typescript/dates/ranges/eachDateIdInRange.d.ts +10 -0
- package/lib/typescript/dates/ranges/eachDateIdInRange.d.ts.map +1 -0
- package/lib/typescript/dates/ranges/normalizeDateRange.d.ts +15 -0
- package/lib/typescript/dates/ranges/normalizeDateRange.d.ts.map +1 -0
- package/lib/typescript/dates/segments/applyDateSegmentChange.d.ts +21 -0
- package/lib/typescript/dates/segments/applyDateSegmentChange.d.ts.map +1 -0
- package/lib/typescript/dates/segments/formatDateSegment.d.ts +13 -0
- package/lib/typescript/dates/segments/formatDateSegment.d.ts.map +1 -0
- package/lib/typescript/dates/segments/getDateFieldSegments.d.ts +13 -0
- package/lib/typescript/dates/segments/getDateFieldSegments.d.ts.map +1 -0
- package/lib/typescript/dates/segments/getDateTimeFieldSegments.d.ts +14 -0
- package/lib/typescript/dates/segments/getDateTimeFieldSegments.d.ts.map +1 -0
- package/lib/typescript/dates/segments/getDateTimeSegmentVisibility.d.ts +8 -0
- package/lib/typescript/dates/segments/getDateTimeSegmentVisibility.d.ts.map +1 -0
- package/lib/typescript/dates/segments/getEmptyDateSegmentText.d.ts +9 -0
- package/lib/typescript/dates/segments/getEmptyDateSegmentText.d.ts.map +1 -0
- package/lib/typescript/dates/segments/parseDateSegment.d.ts +13 -0
- package/lib/typescript/dates/segments/parseDateSegment.d.ts.map +1 -0
- package/lib/typescript/dates/types.d.ts +66 -0
- package/lib/typescript/dates/types.d.ts.map +1 -0
- package/lib/typescript/dates/wire/clampDateParts.d.ts +12 -0
- package/lib/typescript/dates/wire/clampDateParts.d.ts.map +1 -0
- package/lib/typescript/dates/wire/clampMonthParts.d.ts +12 -0
- package/lib/typescript/dates/wire/clampMonthParts.d.ts.map +1 -0
- package/lib/typescript/dates/wire/dateId.d.ts +24 -0
- package/lib/typescript/dates/wire/dateId.d.ts.map +1 -0
- package/lib/typescript/dates/wire/formatDateId.d.ts +12 -0
- package/lib/typescript/dates/wire/formatDateId.d.ts.map +1 -0
- package/lib/typescript/dates/wire/formatMonthId.d.ts +12 -0
- package/lib/typescript/dates/wire/formatMonthId.d.ts.map +1 -0
- package/lib/typescript/dates/wire/isValidDateId.d.ts +13 -0
- package/lib/typescript/dates/wire/isValidDateId.d.ts.map +1 -0
- package/lib/typescript/dates/wire/isValidDateParts.d.ts +9 -0
- package/lib/typescript/dates/wire/isValidDateParts.d.ts.map +1 -0
- package/lib/typescript/dates/wire/isValidMonthId.d.ts +13 -0
- package/lib/typescript/dates/wire/isValidMonthId.d.ts.map +1 -0
- package/lib/typescript/dates/wire/isValidMonthParts.d.ts +9 -0
- package/lib/typescript/dates/wire/isValidMonthParts.d.ts.map +1 -0
- package/lib/typescript/dates/wire/monthId.d.ts +22 -0
- package/lib/typescript/dates/wire/monthId.d.ts.map +1 -0
- package/lib/typescript/dates/wire/parseDateId.d.ts +12 -0
- package/lib/typescript/dates/wire/parseDateId.d.ts.map +1 -0
- package/lib/typescript/dates/wire/parseMonthId.d.ts +12 -0
- package/lib/typescript/dates/wire/parseMonthId.d.ts.map +1 -0
- package/lib/typescript/dates/wire/toMonthId.d.ts +12 -0
- package/lib/typescript/dates/wire/toMonthId.d.ts.map +1 -0
- package/lib/typescript/dates/wire/todayDateId.d.ts +8 -0
- package/lib/typescript/dates/wire/todayDateId.d.ts.map +1 -0
- package/lib/typescript/dates/wire/todayMonthId.d.ts +8 -0
- package/lib/typescript/dates/wire/todayMonthId.d.ts.map +1 -0
- package/lib/typescript/formatNumber.d.ts +19 -0
- package/lib/typescript/formatNumber.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +5 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +2 -0
- package/lib/typescript/types.d.ts.map +1 -0
- package/lib/typescript/utils.d.ts +10 -0
- package/lib/typescript/utils.d.ts.map +1 -0
- package/package.json +50 -0
- package/src/__tests__/applyDateSegmentChange.test.ts +26 -0
- package/src/__tests__/calendarFormatters.test.ts +35 -0
- package/src/__tests__/clampDateParts.test.ts +16 -0
- package/src/__tests__/compareDateIds.test.ts +7 -0
- package/src/__tests__/compareMonthIds.test.ts +19 -0
- package/src/__tests__/dateComponentLabels.test.ts +25 -0
- package/src/__tests__/dateRangeAroundDay.test.ts +10 -0
- package/src/__tests__/dateRangeFromLastNDays.test.ts +8 -0
- package/src/__tests__/dateSegmentHelpers.test.ts +24 -0
- package/src/__tests__/datetimeHelpers.test.ts +65 -0
- package/src/__tests__/displayFormatters.test.ts +34 -0
- package/src/__tests__/eachDateIdInRange.test.ts +11 -0
- package/src/__tests__/formatCalendarMonthYear.test.ts +9 -0
- package/src/__tests__/formatDateForDisplay.test.ts +11 -0
- package/src/__tests__/formatDateId.test.ts +15 -0
- package/src/__tests__/formatMonthId.test.ts +7 -0
- package/src/__tests__/formatNumber.test.ts +35 -0
- package/src/__tests__/getDateFieldSegments.test.ts +35 -0
- package/src/__tests__/getDateTimeFieldSegments.test.ts +140 -0
- package/src/__tests__/getDateTimeSegmentVisibility.test.ts +12 -0
- package/src/__tests__/intlCopy.test.ts +64 -0
- package/src/__tests__/isValidDateId.test.ts +8 -0
- package/src/__tests__/isValidMonthId.test.ts +8 -0
- package/src/__tests__/normalizeDateRange.test.ts +10 -0
- package/src/__tests__/toMonthId.test.ts +7 -0
- package/src/__tests__/todayDateId.test.ts +7 -0
- package/src/__tests__/wireConstructors.test.ts +74 -0
- package/src/dates/calendar/formatCalendarMonthYear.ts +21 -0
- package/src/dates/calendar/formatDateTimeListDateRow.ts +41 -0
- package/src/dates/calendar/formatMonthCalendarMonth.ts +21 -0
- package/src/dates/calendar/formatMonthCalendarYear.ts +9 -0
- package/src/dates/calendar/getCalendarWeekdayLabels.ts +23 -0
- package/src/dates/datetime/clampDateTimeId.ts +25 -0
- package/src/dates/datetime/compareDateTimeIds.ts +23 -0
- package/src/dates/datetime/dateTimeId.ts +36 -0
- package/src/dates/datetime/formatDateTimeId.ts +35 -0
- package/src/dates/datetime/formatDateTimeListHour.ts +14 -0
- package/src/dates/datetime/formatDateTimeListMinute.ts +9 -0
- package/src/dates/datetime/formatDateTimeListPeriod.ts +12 -0
- package/src/dates/datetime/isLocaleHour12.ts +23 -0
- package/src/dates/datetime/isValidDateTimeId.ts +18 -0
- package/src/dates/datetime/nowDateTimeId.ts +53 -0
- package/src/dates/datetime/parseDateTimeId.ts +24 -0
- package/src/dates/display/formatDateForDisplay.ts +21 -0
- package/src/dates/display/formatDateRangeForDisplay.ts +23 -0
- package/src/dates/display/formatDateTimeForDisplay.ts +37 -0
- package/src/dates/display/formatMonthForDisplay.ts +26 -0
- package/src/dates/index.ts +86 -0
- package/src/dates/internal/brand.ts +11 -0
- package/src/dates/internal/calendarHelpers.ts +18 -0
- package/src/dates/internal/clampHelpers.ts +15 -0
- package/src/dates/internal/dateIdToNativeDate.ts +15 -0
- package/src/dates/internal/intlCache.ts +40 -0
- package/src/dates/internal/intlCopy.ts +75 -0
- package/src/dates/internal/segmentBuilders.ts +94 -0
- package/src/dates/labels/dateComponentLabels.ts +79 -0
- package/src/dates/ranges/compareDateIds.ts +21 -0
- package/src/dates/ranges/compareMonthIds.ts +26 -0
- package/src/dates/ranges/dateRangeAroundDay.ts +24 -0
- package/src/dates/ranges/dateRangeFromLastNDays.ts +26 -0
- package/src/dates/ranges/eachDateIdInRange.ts +21 -0
- package/src/dates/ranges/normalizeDateRange.ts +18 -0
- package/src/dates/segments/applyDateSegmentChange.ts +57 -0
- package/src/dates/segments/formatDateSegment.ts +18 -0
- package/src/dates/segments/getDateFieldSegments.ts +45 -0
- package/src/dates/segments/getDateTimeFieldSegments.ts +126 -0
- package/src/dates/segments/getDateTimeSegmentVisibility.ts +14 -0
- package/src/dates/segments/getEmptyDateSegmentText.ts +12 -0
- package/src/dates/segments/parseDateSegment.ts +25 -0
- package/src/dates/types.ts +80 -0
- package/src/dates/wire/clampDateParts.ts +17 -0
- package/src/dates/wire/clampMonthParts.ts +15 -0
- package/src/dates/wire/dateId.ts +44 -0
- package/src/dates/wire/formatDateId.ts +20 -0
- package/src/dates/wire/formatMonthId.ts +16 -0
- package/src/dates/wire/isValidDateId.ts +22 -0
- package/src/dates/wire/isValidDateParts.ts +17 -0
- package/src/dates/wire/isValidMonthId.ts +22 -0
- package/src/dates/wire/isValidMonthParts.ts +11 -0
- package/src/dates/wire/monthId.ts +42 -0
- package/src/dates/wire/parseDateId.ts +20 -0
- package/src/dates/wire/parseMonthId.ts +20 -0
- package/src/dates/wire/toMonthId.ts +17 -0
- package/src/dates/wire/todayDateId.ts +12 -0
- package/src/dates/wire/todayMonthId.ts +12 -0
- package/src/formatNumber.ts +56 -0
- package/src/index.ts +82 -0
- package/src/types.ts +1 -0
- package/src/utils.ts +29 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { DateTimeGranularity, DateTimeId, DateTimeParts } from '../types';
|
|
2
|
+
import { formatDateTimeId } from './formatDateTimeId';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Returns the local device date/time as a `DateTimeId`, truncated to the requested granularity.
|
|
6
|
+
*
|
|
7
|
+
* @param options - Optional granularity; defaults to `'minute'`.
|
|
8
|
+
* @returns Wire `DateTimeId` for the current local time.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* nowDateTimeId({ granularity: 'minute' }) // '2026-07-28T14:30'
|
|
12
|
+
*/
|
|
13
|
+
export function nowDateTimeId(options?: { granularity?: DateTimeGranularity }): DateTimeId {
|
|
14
|
+
const now = new Date();
|
|
15
|
+
const parts: DateTimeParts = {
|
|
16
|
+
year: now.getFullYear(),
|
|
17
|
+
month: now.getMonth() + 1,
|
|
18
|
+
day: now.getDate(),
|
|
19
|
+
hour: now.getHours(),
|
|
20
|
+
minute: now.getMinutes(),
|
|
21
|
+
second: now.getSeconds(),
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
switch (options?.granularity ?? 'minute') {
|
|
25
|
+
case 'day':
|
|
26
|
+
return formatDateTimeId({
|
|
27
|
+
year: parts.year,
|
|
28
|
+
month: parts.month,
|
|
29
|
+
day: parts.day,
|
|
30
|
+
hour: 0,
|
|
31
|
+
minute: 0,
|
|
32
|
+
});
|
|
33
|
+
case 'hour':
|
|
34
|
+
return formatDateTimeId({
|
|
35
|
+
year: parts.year,
|
|
36
|
+
month: parts.month,
|
|
37
|
+
day: parts.day,
|
|
38
|
+
hour: parts.hour,
|
|
39
|
+
minute: 0,
|
|
40
|
+
});
|
|
41
|
+
case 'minute':
|
|
42
|
+
return formatDateTimeId({
|
|
43
|
+
year: parts.year,
|
|
44
|
+
month: parts.month,
|
|
45
|
+
day: parts.day,
|
|
46
|
+
hour: parts.hour,
|
|
47
|
+
minute: parts.minute,
|
|
48
|
+
});
|
|
49
|
+
case 'second':
|
|
50
|
+
default:
|
|
51
|
+
return formatDateTimeId(parts);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { parseISO } from 'date-fns';
|
|
2
|
+
import type { DateTimeId, DateTimeParts } from '../types';
|
|
3
|
+
import { isValidDateTimeId } from './isValidDateTimeId';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Parses a wire `DateTimeId` into numeric parts, or `null` when invalid.
|
|
7
|
+
*
|
|
8
|
+
* @param dateTimeId - Wire date-time string.
|
|
9
|
+
* @returns Parsed parts, or `null` when `dateTimeId` is invalid.
|
|
10
|
+
*/
|
|
11
|
+
export function parseDateTimeId(dateTimeId: DateTimeId): DateTimeParts | null {
|
|
12
|
+
if (!isValidDateTimeId(dateTimeId)) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const date = parseISO(dateTimeId);
|
|
16
|
+
return {
|
|
17
|
+
year: date.getFullYear(),
|
|
18
|
+
month: date.getMonth() + 1,
|
|
19
|
+
day: date.getDate(),
|
|
20
|
+
hour: date.getHours(),
|
|
21
|
+
minute: date.getMinutes(),
|
|
22
|
+
second: date.getSeconds(),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { dateIdToNativeDate } from '../internal/dateIdToNativeDate';
|
|
2
|
+
import { getCachedDateFormatter } from '../internal/intlCache';
|
|
3
|
+
import type { DateId, FormatDateDisplayOptions } from '../types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Formats a locale-aware date string for UI labels (never store the result in form state).
|
|
7
|
+
*
|
|
8
|
+
* @param dateId - Wire date string (`YYYY-MM-DD`).
|
|
9
|
+
* @param options - Locale, date style, and optional time zone.
|
|
10
|
+
* @returns Locale-formatted date string.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* formatDateForDisplay('2026-07-28', { locale: 'en-US' }) // e.g. '7/28/26'
|
|
14
|
+
*/
|
|
15
|
+
export function formatDateForDisplay(dateId: DateId, options?: FormatDateDisplayOptions): string {
|
|
16
|
+
const formatter = getCachedDateFormatter(options?.locale ?? 'en-US', {
|
|
17
|
+
dateStyle: options?.dateStyle ?? 'short',
|
|
18
|
+
...(options?.timeZone ? { timeZone: options.timeZone } : {}),
|
|
19
|
+
});
|
|
20
|
+
return formatter.format(dateIdToNativeDate(dateId));
|
|
21
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { getDateRangeSeparator } from '../internal/intlCopy';
|
|
2
|
+
import type { DateId, DateRangeDisplayOptions } from '../types';
|
|
3
|
+
import { formatDateForDisplay } from './formatDateForDisplay';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Formats an inclusive date range for display.
|
|
7
|
+
*
|
|
8
|
+
* @param range - Start and end wire date ids.
|
|
9
|
+
* @param options - Locale, separator, and display options passed to `formatDateForDisplay`.
|
|
10
|
+
* @returns Formatted range string.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* formatDateRangeForDisplay({ startId: '2026-07-01', endId: '2026-07-28' })
|
|
14
|
+
*/
|
|
15
|
+
export function formatDateRangeForDisplay(
|
|
16
|
+
range: { startId: DateId; endId: DateId },
|
|
17
|
+
options?: DateRangeDisplayOptions,
|
|
18
|
+
): string {
|
|
19
|
+
const separator = options?.rangeSeparator ?? getDateRangeSeparator(options?.locale);
|
|
20
|
+
const start = formatDateForDisplay(range.startId, options);
|
|
21
|
+
const end = formatDateForDisplay(range.endId, options);
|
|
22
|
+
return `${start}${separator}${end}`;
|
|
23
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { getCachedDateFormatter } from '../internal/intlCache';
|
|
2
|
+
import { parseDateTimeId } from '../datetime/parseDateTimeId';
|
|
3
|
+
import type { DateTimeId, FormatDateTimeDisplayOptions } from '../types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Formats a locale-aware date-time string for UI labels.
|
|
7
|
+
*
|
|
8
|
+
* @param dateTimeId - Wire date-time string.
|
|
9
|
+
* @param options - Locale, date/time styles, and optional time zone.
|
|
10
|
+
* @returns Locale-formatted date-time string, or `''` when invalid.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* formatDateTimeForDisplay('2026-07-28T10:01', { locale: 'en-US' })
|
|
14
|
+
*/
|
|
15
|
+
export function formatDateTimeForDisplay(
|
|
16
|
+
dateTimeId: DateTimeId,
|
|
17
|
+
options?: FormatDateTimeDisplayOptions,
|
|
18
|
+
): string {
|
|
19
|
+
const parts = parseDateTimeId(dateTimeId);
|
|
20
|
+
if (!parts) {
|
|
21
|
+
return '';
|
|
22
|
+
}
|
|
23
|
+
const date = new Date(
|
|
24
|
+
parts.year,
|
|
25
|
+
parts.month - 1,
|
|
26
|
+
parts.day,
|
|
27
|
+
parts.hour,
|
|
28
|
+
parts.minute,
|
|
29
|
+
parts.second ?? 0,
|
|
30
|
+
);
|
|
31
|
+
const formatter = getCachedDateFormatter(options?.locale ?? 'en-US', {
|
|
32
|
+
dateStyle: options?.dateStyle ?? 'medium',
|
|
33
|
+
timeStyle: options?.timeStyle ?? 'short',
|
|
34
|
+
...(options?.timeZone ? { timeZone: options.timeZone } : {}),
|
|
35
|
+
});
|
|
36
|
+
return formatter.format(date);
|
|
37
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { dateIdToNativeDate } from '../internal/dateIdToNativeDate';
|
|
2
|
+
import { getCachedDateFormatter } from '../internal/intlCache';
|
|
3
|
+
import type { FormatDateDisplayOptions, MonthId } from '../types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Formats a locale-aware month/year string for UI labels.
|
|
7
|
+
*
|
|
8
|
+
* @param monthId - Wire month string (`YYYY-MM-01`).
|
|
9
|
+
* @param options - Locale, date style, and optional time zone.
|
|
10
|
+
* @returns Locale-formatted month/year string.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* formatMonthForDisplay('2026-07-01', { locale: 'en-US' }) // e.g. '07/2026'
|
|
14
|
+
*/
|
|
15
|
+
export function formatMonthForDisplay(
|
|
16
|
+
monthId: MonthId,
|
|
17
|
+
options?: FormatDateDisplayOptions,
|
|
18
|
+
): string {
|
|
19
|
+
const formatter = getCachedDateFormatter(options?.locale ?? 'en-US', {
|
|
20
|
+
month: '2-digit',
|
|
21
|
+
year: 'numeric',
|
|
22
|
+
...(options?.dateStyle === 'long' ? { month: 'long', year: 'numeric' } : {}),
|
|
23
|
+
...(options?.timeZone ? { timeZone: options.timeZone } : {}),
|
|
24
|
+
});
|
|
25
|
+
return formatter.format(dateIdToNativeDate(monthId));
|
|
26
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Date / date-time formatters.
|
|
3
|
+
*
|
|
4
|
+
* Wire ids (`DateId`, `MonthId`, `DateTimeId`) are fixed-format strings for state and APIs.
|
|
5
|
+
* Display helpers return locale-dependent strings for UI labels — never store those in form state.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export type {
|
|
9
|
+
DateFieldMode,
|
|
10
|
+
DateFormatOptions,
|
|
11
|
+
DateId,
|
|
12
|
+
DateParts,
|
|
13
|
+
DateRangeDisplayOptions,
|
|
14
|
+
DateSegment,
|
|
15
|
+
DateSegmentType,
|
|
16
|
+
DateTimeGranularity,
|
|
17
|
+
DateTimeId,
|
|
18
|
+
DateTimeParts,
|
|
19
|
+
FormatDateDisplayOptions,
|
|
20
|
+
FormatDateTimeDisplayOptions,
|
|
21
|
+
MonthId,
|
|
22
|
+
MonthParts,
|
|
23
|
+
TimeParts,
|
|
24
|
+
} from './types';
|
|
25
|
+
|
|
26
|
+
export { clampDateParts } from './wire/clampDateParts';
|
|
27
|
+
export { clampMonthParts } from './wire/clampMonthParts';
|
|
28
|
+
export { dateId } from './wire/dateId';
|
|
29
|
+
export { monthId } from './wire/monthId';
|
|
30
|
+
export { formatDateId } from './wire/formatDateId';
|
|
31
|
+
export { formatMonthId } from './wire/formatMonthId';
|
|
32
|
+
export { isValidDateId } from './wire/isValidDateId';
|
|
33
|
+
export { isValidDateParts } from './wire/isValidDateParts';
|
|
34
|
+
export { isValidMonthId } from './wire/isValidMonthId';
|
|
35
|
+
export { isValidMonthParts } from './wire/isValidMonthParts';
|
|
36
|
+
export { parseDateId } from './wire/parseDateId';
|
|
37
|
+
export { parseMonthId } from './wire/parseMonthId';
|
|
38
|
+
export { toMonthId } from './wire/toMonthId';
|
|
39
|
+
export { todayDateId } from './wire/todayDateId';
|
|
40
|
+
export { todayMonthId } from './wire/todayMonthId';
|
|
41
|
+
|
|
42
|
+
export { clampDateTimeId } from './datetime/clampDateTimeId';
|
|
43
|
+
export { compareDateTimeIds } from './datetime/compareDateTimeIds';
|
|
44
|
+
export { dateTimeId } from './datetime/dateTimeId';
|
|
45
|
+
export { formatDateTimeId } from './datetime/formatDateTimeId';
|
|
46
|
+
export { isLocaleHour12 } from './datetime/isLocaleHour12';
|
|
47
|
+
export { formatDateTimeListHour } from './datetime/formatDateTimeListHour';
|
|
48
|
+
export { formatDateTimeListMinute } from './datetime/formatDateTimeListMinute';
|
|
49
|
+
export { formatDateTimeListPeriod } from './datetime/formatDateTimeListPeriod';
|
|
50
|
+
export { isValidDateTimeId } from './datetime/isValidDateTimeId';
|
|
51
|
+
export { nowDateTimeId } from './datetime/nowDateTimeId';
|
|
52
|
+
export { parseDateTimeId } from './datetime/parseDateTimeId';
|
|
53
|
+
|
|
54
|
+
export { formatDateForDisplay } from './display/formatDateForDisplay';
|
|
55
|
+
export { formatDateRangeForDisplay } from './display/formatDateRangeForDisplay';
|
|
56
|
+
export { formatDateTimeForDisplay } from './display/formatDateTimeForDisplay';
|
|
57
|
+
export { formatMonthForDisplay } from './display/formatMonthForDisplay';
|
|
58
|
+
|
|
59
|
+
export { compareDateIds } from './ranges/compareDateIds';
|
|
60
|
+
export { compareMonthIds } from './ranges/compareMonthIds';
|
|
61
|
+
export { dateRangeAroundDay } from './ranges/dateRangeAroundDay';
|
|
62
|
+
export { dateRangeFromLastNDays } from './ranges/dateRangeFromLastNDays';
|
|
63
|
+
export { eachDateIdInRange } from './ranges/eachDateIdInRange';
|
|
64
|
+
export { normalizeDateRange } from './ranges/normalizeDateRange';
|
|
65
|
+
|
|
66
|
+
export { applyDateSegmentChange } from './segments/applyDateSegmentChange';
|
|
67
|
+
export { formatDateSegment } from './segments/formatDateSegment';
|
|
68
|
+
export { getDateFieldSegments } from './segments/getDateFieldSegments';
|
|
69
|
+
export { getDateTimeFieldSegments } from './segments/getDateTimeFieldSegments';
|
|
70
|
+
export { getDateTimeSegmentVisibility } from './segments/getDateTimeSegmentVisibility';
|
|
71
|
+
export { getEmptyDateSegmentText } from './segments/getEmptyDateSegmentText';
|
|
72
|
+
export { parseDateSegment } from './segments/parseDateSegment';
|
|
73
|
+
|
|
74
|
+
export { formatCalendarMonthYear } from './calendar/formatCalendarMonthYear';
|
|
75
|
+
export { formatDateTimeListDateRow } from './calendar/formatDateTimeListDateRow';
|
|
76
|
+
export { formatMonthCalendarMonth } from './calendar/formatMonthCalendarMonth';
|
|
77
|
+
export { formatMonthCalendarYear } from './calendar/formatMonthCalendarYear';
|
|
78
|
+
export { getCalendarWeekdayLabels } from './calendar/getCalendarWeekdayLabels';
|
|
79
|
+
|
|
80
|
+
export type { DateComponentLabels } from './labels/dateComponentLabels';
|
|
81
|
+
export {
|
|
82
|
+
DEFAULT_DATE_COMPONENT_LABELS,
|
|
83
|
+
formatSelectYear,
|
|
84
|
+
getDateSegmentAccessibilityLabel,
|
|
85
|
+
resolveDateComponentLabels,
|
|
86
|
+
} from './labels/dateComponentLabels';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { DateId, DateTimeId, MonthId } from '../types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @internal
|
|
5
|
+
* Unchecked brand casts for wire producers that have already guaranteed a
|
|
6
|
+
* well-formed wire string. Callers outside `@cdx-ui/formatters` must go through
|
|
7
|
+
* the validating smart constructors (`dateId`, `monthId`, `dateTimeId`) instead.
|
|
8
|
+
*/
|
|
9
|
+
export const asDateId = (value: string): DateId => value as DateId;
|
|
10
|
+
export const asMonthId = (value: string): MonthId => value as MonthId;
|
|
11
|
+
export const asDateTimeId = (value: string): DateTimeId => value as DateTimeId;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { DateFormatOptions } from '../types';
|
|
2
|
+
import { getCachedDateFormatter } from './intlCache';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export function formatCalendarWeekday(
|
|
8
|
+
weekdayIndex: number,
|
|
9
|
+
options?: DateFormatOptions & { weekday?: 'short' | 'narrow' | 'long' },
|
|
10
|
+
): string {
|
|
11
|
+
// 2023-01-01 was a Sunday — index 0..6 maps Sun..Sat regardless of locale week start.
|
|
12
|
+
const ref = new Date(2023, 0, 1 + weekdayIndex);
|
|
13
|
+
const formatter = getCachedDateFormatter(options?.locale ?? 'en-US', {
|
|
14
|
+
weekday: options?.weekday ?? 'short',
|
|
15
|
+
...(options?.timeZone ? { timeZone: options.timeZone } : {}),
|
|
16
|
+
});
|
|
17
|
+
return formatter.format(ref);
|
|
18
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { getDaysInMonth } from 'date-fns';
|
|
2
|
+
import type { DateParts } from '../types';
|
|
3
|
+
|
|
4
|
+
export function partsToDate(parts: DateParts): Date {
|
|
5
|
+
return new Date(parts.year, parts.month - 1, parts.day);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function clampMonth(month: number): number {
|
|
9
|
+
return Math.min(12, Math.max(1, month));
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function clampDay(year: number, month: number, day: number): number {
|
|
13
|
+
const maxDay = getDaysInMonth(new Date(year, month - 1, 1));
|
|
14
|
+
return Math.min(maxDay, Math.max(1, day));
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { parse } from 'date-fns';
|
|
2
|
+
import type { DateId, MonthId } from '../types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Local calendar `Date` from a wire id. Never use `parseISO` for date-only ids
|
|
6
|
+
* (UTC midnight shifts the calendar day in western time zones).
|
|
7
|
+
*
|
|
8
|
+
* Accepts either a `DateId` or `MonthId` — both share the `YYYY-MM-DD` wire
|
|
9
|
+
* shape and only the date portion is parsed.
|
|
10
|
+
*
|
|
11
|
+
* @internal Not part of the public package API.
|
|
12
|
+
*/
|
|
13
|
+
export function dateIdToNativeDate(dateId: DateId | MonthId): Date {
|
|
14
|
+
return parse(dateId, 'yyyy-MM-dd', new Date());
|
|
15
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { DateFormatOptions } from '../types';
|
|
2
|
+
|
|
3
|
+
const formatterCache = new Map<string, Intl.DateTimeFormat>();
|
|
4
|
+
|
|
5
|
+
function cacheKey(locale: string, options: Intl.DateTimeFormatOptions): string {
|
|
6
|
+
return `${locale}:${JSON.stringify(options)}`;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Cached `Intl.DateTimeFormat` factory for display helpers.
|
|
11
|
+
*
|
|
12
|
+
* @internal Not part of the public package API — prefer `formatDateForDisplay` and related helpers.
|
|
13
|
+
*/
|
|
14
|
+
export function createDateFormatter(
|
|
15
|
+
options: Intl.DateTimeFormatOptions & DateFormatOptions,
|
|
16
|
+
): Intl.DateTimeFormat {
|
|
17
|
+
const { locale = 'en-US', timeZone, calendar, ...intlOptions } = options;
|
|
18
|
+
return new Intl.DateTimeFormat(locale, {
|
|
19
|
+
...intlOptions,
|
|
20
|
+
...(timeZone ? { timeZone } : {}),
|
|
21
|
+
...(calendar ? { calendar } : {}),
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
export function getCachedDateFormatter(
|
|
29
|
+
locale: string,
|
|
30
|
+
options: Intl.DateTimeFormatOptions & DateFormatOptions,
|
|
31
|
+
): Intl.DateTimeFormat {
|
|
32
|
+
const key = cacheKey(locale, options);
|
|
33
|
+
const cached = formatterCache.get(key);
|
|
34
|
+
if (cached) {
|
|
35
|
+
return cached;
|
|
36
|
+
}
|
|
37
|
+
const formatter = createDateFormatter({ locale, ...options });
|
|
38
|
+
formatterCache.set(key, formatter);
|
|
39
|
+
return formatter;
|
|
40
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const DEFAULT_LOCALE = 'en-US';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Locale-aware relative "today" label (e.g. `Today`, `aujourd'hui`).
|
|
5
|
+
* Falls back when `Intl.RelativeTimeFormat` is missing (Hermes / incomplete Intl).
|
|
6
|
+
*/
|
|
7
|
+
export function formatRelativeToday(locale = DEFAULT_LOCALE): string {
|
|
8
|
+
if (
|
|
9
|
+
typeof Intl !== 'undefined' &&
|
|
10
|
+
typeof (Intl as typeof Intl & { RelativeTimeFormat?: unknown }).RelativeTimeFormat ===
|
|
11
|
+
'function'
|
|
12
|
+
) {
|
|
13
|
+
try {
|
|
14
|
+
return new Intl.RelativeTimeFormat(locale, { numeric: 'auto' }).format(0, 'day');
|
|
15
|
+
} catch {
|
|
16
|
+
// Incomplete Intl implementations can throw on construct/format.
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return 'Today';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Locale-aware day-period label (AM/PM or locale equivalent) for a 0–23 hour value. */
|
|
23
|
+
export function formatDayPeriodFromHour(hour: number, locale = DEFAULT_LOCALE): string {
|
|
24
|
+
const fallback = hour < 12 ? 'AM' : 'PM';
|
|
25
|
+
// Hermes (React Native) does not reliably ship `Intl.DateTimeFormat.prototype.formatToParts`;
|
|
26
|
+
// guard so native falls back to AM/PM instead of throwing.
|
|
27
|
+
if (
|
|
28
|
+
typeof Intl === 'undefined' ||
|
|
29
|
+
!('DateTimeFormat' in Intl) ||
|
|
30
|
+
!('formatToParts' in Intl.DateTimeFormat.prototype)
|
|
31
|
+
) {
|
|
32
|
+
return fallback;
|
|
33
|
+
}
|
|
34
|
+
const sampleHour = hour < 12 ? 9 : 15;
|
|
35
|
+
const parts = new Intl.DateTimeFormat(locale, { hour: 'numeric', hour12: true }).formatToParts(
|
|
36
|
+
new Date(2000, 0, 1, sampleHour, 0),
|
|
37
|
+
);
|
|
38
|
+
return parts.find((part) => part.type === 'dayPeriod')?.value ?? fallback;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Locale-aware separator between two formatted dates in a range label. */
|
|
42
|
+
export function getDateRangeSeparator(locale = DEFAULT_LOCALE): string {
|
|
43
|
+
if (
|
|
44
|
+
typeof Intl !== 'undefined' &&
|
|
45
|
+
'DateTimeFormat' in Intl &&
|
|
46
|
+
'formatRangeToParts' in Intl.DateTimeFormat.prototype
|
|
47
|
+
) {
|
|
48
|
+
const formatter = new Intl.DateTimeFormat(locale);
|
|
49
|
+
const parts = formatter.formatRangeToParts(new Date(2000, 0, 15), new Date(2000, 0, 16));
|
|
50
|
+
|
|
51
|
+
let pastFirstYear = false;
|
|
52
|
+
let separator = '';
|
|
53
|
+
for (const part of parts) {
|
|
54
|
+
if (!pastFirstYear) {
|
|
55
|
+
if (part.type === 'year') {
|
|
56
|
+
pastFirstYear = true;
|
|
57
|
+
}
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (part.type === 'month' || part.type === 'day') {
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
if (part.type === 'literal') {
|
|
64
|
+
separator += part.value;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const trimmed = separator.trim();
|
|
69
|
+
if (trimmed) {
|
|
70
|
+
return ` ${trimmed} `;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return ' – ';
|
|
75
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { DateFieldMode, DateSegment, DateSegmentType } from '../types';
|
|
2
|
+
import { getCachedDateFormatter } from './intlCache';
|
|
3
|
+
|
|
4
|
+
export const DATE_FIELD_FORMAT_OPTIONS: Record<DateFieldMode, Intl.DateTimeFormatOptions> = {
|
|
5
|
+
date: { year: 'numeric', month: '2-digit', day: '2-digit' },
|
|
6
|
+
month: { year: 'numeric', month: '2-digit' },
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const EMPTY_DATE_SEGMENT_TEXT: Partial<Record<DateSegmentType, string>> = {
|
|
10
|
+
year: 'YYYY',
|
|
11
|
+
month: 'MM',
|
|
12
|
+
day: 'DD',
|
|
13
|
+
hour: 'hh',
|
|
14
|
+
minute: 'mm',
|
|
15
|
+
second: 'ss',
|
|
16
|
+
dayPeriod: 'AM',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const EMPTY_TIME_SEGMENT_TEXT: Record<'hour' | 'minute' | 'second' | 'dayPeriod', string> = {
|
|
20
|
+
hour: 'hh',
|
|
21
|
+
minute: 'mm',
|
|
22
|
+
second: 'ss',
|
|
23
|
+
dayPeriod: 'AM',
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export function padSegment(type: DateSegmentType, value: number): string {
|
|
27
|
+
if (type === 'year') {
|
|
28
|
+
return String(value).padStart(4, '0');
|
|
29
|
+
}
|
|
30
|
+
if (type === 'month' || type === 'day' || type === 'minute' || type === 'second') {
|
|
31
|
+
return String(value).padStart(2, '0');
|
|
32
|
+
}
|
|
33
|
+
if (type === 'hour') {
|
|
34
|
+
return String(value).padStart(2, '0');
|
|
35
|
+
}
|
|
36
|
+
return String(value);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function buildEmptyDateFieldSegments(mode: DateFieldMode, locale: string): DateSegment[] {
|
|
40
|
+
const formatter = getCachedDateFormatter(locale, DATE_FIELD_FORMAT_OPTIONS[mode]);
|
|
41
|
+
const intlParts = formatter.formatToParts(new Date(2000, 0, 15));
|
|
42
|
+
const segments: DateSegment[] = [];
|
|
43
|
+
|
|
44
|
+
for (const part of intlParts) {
|
|
45
|
+
if (part.type === 'literal') {
|
|
46
|
+
segments.push({ type: 'literal', text: part.value, isEditable: false });
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (part.type === 'year' || part.type === 'month' || (part.type === 'day' && mode === 'date')) {
|
|
51
|
+
segments.push({
|
|
52
|
+
type: part.type,
|
|
53
|
+
text: EMPTY_DATE_SEGMENT_TEXT[part.type] ?? part.value,
|
|
54
|
+
isEditable: true,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return segments;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function buildDateFieldSegments(
|
|
63
|
+
values: { year: number; month: number; day: number },
|
|
64
|
+
mode: DateFieldMode,
|
|
65
|
+
locale: string,
|
|
66
|
+
): DateSegment[] {
|
|
67
|
+
const formatter = getCachedDateFormatter(locale, DATE_FIELD_FORMAT_OPTIONS[mode]);
|
|
68
|
+
const refDate =
|
|
69
|
+
mode === 'month'
|
|
70
|
+
? new Date(values.year, values.month - 1, 1)
|
|
71
|
+
: new Date(values.year, values.month - 1, values.day);
|
|
72
|
+
const intlParts = formatter.formatToParts(refDate);
|
|
73
|
+
const segments: DateSegment[] = [];
|
|
74
|
+
|
|
75
|
+
for (const part of intlParts) {
|
|
76
|
+
if (part.type === 'literal') {
|
|
77
|
+
segments.push({ type: 'literal', text: part.value, isEditable: false });
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (part.type === 'year' || part.type === 'month' || (part.type === 'day' && mode === 'date')) {
|
|
82
|
+
const value =
|
|
83
|
+
part.type === 'year' ? values.year : part.type === 'month' ? values.month : values.day;
|
|
84
|
+
segments.push({
|
|
85
|
+
type: part.type,
|
|
86
|
+
text: padSegment(part.type, value),
|
|
87
|
+
value,
|
|
88
|
+
isEditable: true,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return segments;
|
|
94
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { DateSegmentType } from '../types';
|
|
2
|
+
|
|
3
|
+
/** Overridable UI copy for date pickers, calendars, and segmented date fields. */
|
|
4
|
+
export interface DateComponentLabels {
|
|
5
|
+
openDatePicker: string;
|
|
6
|
+
openDateTimePicker: string;
|
|
7
|
+
openDateRangePicker: string;
|
|
8
|
+
openMonthPicker: string;
|
|
9
|
+
showCalendar: string;
|
|
10
|
+
showYearPicker: string;
|
|
11
|
+
showMonths: string;
|
|
12
|
+
previousMonth: string;
|
|
13
|
+
nextMonth: string;
|
|
14
|
+
previousYear: string;
|
|
15
|
+
nextYear: string;
|
|
16
|
+
/** Use `{year}` as the year placeholder. */
|
|
17
|
+
selectYear: string;
|
|
18
|
+
dateFieldKeyboardInput: string;
|
|
19
|
+
segmentYear: string;
|
|
20
|
+
segmentMonth: string;
|
|
21
|
+
segmentDay: string;
|
|
22
|
+
segmentHour: string;
|
|
23
|
+
segmentMinute: string;
|
|
24
|
+
segmentSecond: string;
|
|
25
|
+
segmentDayPeriod: string;
|
|
26
|
+
rangeSeparator: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const DEFAULT_DATE_COMPONENT_LABELS: DateComponentLabels = {
|
|
30
|
+
openDatePicker: 'Open date picker',
|
|
31
|
+
openDateTimePicker: 'Open date time picker',
|
|
32
|
+
openDateRangePicker: 'Open date range picker',
|
|
33
|
+
openMonthPicker: 'Open month picker',
|
|
34
|
+
showCalendar: 'Show calendar',
|
|
35
|
+
showYearPicker: 'Show year picker',
|
|
36
|
+
showMonths: 'Show months',
|
|
37
|
+
previousMonth: 'Previous month',
|
|
38
|
+
nextMonth: 'Next month',
|
|
39
|
+
previousYear: 'Previous year',
|
|
40
|
+
nextYear: 'Next year',
|
|
41
|
+
selectYear: 'Select year {year}',
|
|
42
|
+
dateFieldKeyboardInput: 'Date field keyboard input',
|
|
43
|
+
segmentYear: 'Year',
|
|
44
|
+
segmentMonth: 'Month',
|
|
45
|
+
segmentDay: 'Day',
|
|
46
|
+
segmentHour: 'Hour',
|
|
47
|
+
segmentMinute: 'Minute',
|
|
48
|
+
segmentSecond: 'Second',
|
|
49
|
+
segmentDayPeriod: 'AM/PM',
|
|
50
|
+
rangeSeparator: '–',
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export function resolveDateComponentLabels(
|
|
54
|
+
partial?: Partial<DateComponentLabels>,
|
|
55
|
+
): DateComponentLabels {
|
|
56
|
+
return { ...DEFAULT_DATE_COMPONENT_LABELS, ...partial };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function formatSelectYear(labels: DateComponentLabels, year: number): string {
|
|
60
|
+
return labels.selectYear.replace('{year}', String(year));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const SEGMENT_LABEL_KEYS: Partial<Record<DateSegmentType, keyof DateComponentLabels>> = {
|
|
64
|
+
year: 'segmentYear',
|
|
65
|
+
month: 'segmentMonth',
|
|
66
|
+
day: 'segmentDay',
|
|
67
|
+
hour: 'segmentHour',
|
|
68
|
+
minute: 'segmentMinute',
|
|
69
|
+
second: 'segmentSecond',
|
|
70
|
+
dayPeriod: 'segmentDayPeriod',
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export function getDateSegmentAccessibilityLabel(
|
|
74
|
+
type: DateSegmentType,
|
|
75
|
+
labels: DateComponentLabels,
|
|
76
|
+
): string | undefined {
|
|
77
|
+
const key = SEGMENT_LABEL_KEYS[type];
|
|
78
|
+
return key ? labels[key] : undefined;
|
|
79
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { compareAsc } from 'date-fns';
|
|
2
|
+
import { dateIdToNativeDate } from '../internal/dateIdToNativeDate';
|
|
3
|
+
import type { DateId } from '../types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Compares two wire dates.
|
|
7
|
+
*
|
|
8
|
+
* @param a - First wire date.
|
|
9
|
+
* @param b - Second wire date.
|
|
10
|
+
* @returns `-1` if `a` is earlier, `1` if later, `0` if equal.
|
|
11
|
+
*/
|
|
12
|
+
export function compareDateIds(a: DateId, b: DateId): -1 | 0 | 1 {
|
|
13
|
+
const result = compareAsc(dateIdToNativeDate(a), dateIdToNativeDate(b));
|
|
14
|
+
if (result < 0) {
|
|
15
|
+
return -1;
|
|
16
|
+
}
|
|
17
|
+
if (result > 0) {
|
|
18
|
+
return 1;
|
|
19
|
+
}
|
|
20
|
+
return 0;
|
|
21
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { parseMonthId } from '../wire/parseMonthId';
|
|
2
|
+
import type { MonthId } from '../types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Compares two wire months chronologically.
|
|
6
|
+
*
|
|
7
|
+
* @param a - First wire month (`YYYY-MM-01`).
|
|
8
|
+
* @param b - Second wire month (`YYYY-MM-01`).
|
|
9
|
+
* @returns `-1` if `a` is earlier, `1` if later, `0` if equal or either is invalid.
|
|
10
|
+
*/
|
|
11
|
+
export function compareMonthIds(a: MonthId, b: MonthId): -1 | 0 | 1 {
|
|
12
|
+
const pa = parseMonthId(a);
|
|
13
|
+
const pb = parseMonthId(b);
|
|
14
|
+
if (!pa || !pb) {
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
17
|
+
const av = pa.year * 12 + pa.month;
|
|
18
|
+
const bv = pb.year * 12 + pb.month;
|
|
19
|
+
if (av < bv) {
|
|
20
|
+
return -1;
|
|
21
|
+
}
|
|
22
|
+
if (av > bv) {
|
|
23
|
+
return 1;
|
|
24
|
+
}
|
|
25
|
+
return 0;
|
|
26
|
+
}
|