@intech-software/chronera 0.1.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/LICENSE +190 -0
- package/README.md +6644 -0
- package/dist/calendar/buddhist/adapter.d.ts +2 -0
- package/dist/calendar/buddhist/adapter.js +33 -0
- package/dist/calendar/buddhist/adapter.js.map +1 -0
- package/dist/calendar/buddhist/constants.d.ts +3 -0
- package/dist/calendar/buddhist/constants.js +14 -0
- package/dist/calendar/buddhist/constants.js.map +1 -0
- package/dist/calendar/buddhist/index.d.ts +3 -0
- package/dist/calendar/buddhist/index.js +4 -0
- package/dist/calendar/buddhist/index.js.map +1 -0
- package/dist/calendar/buddhist/validator.d.ts +4 -0
- package/dist/calendar/buddhist/validator.js +60 -0
- package/dist/calendar/buddhist/validator.js.map +1 -0
- package/dist/calendar/gregory/absolute-day.d.ts +12 -0
- package/dist/calendar/gregory/absolute-day.js +14 -0
- package/dist/calendar/gregory/absolute-day.js.map +1 -0
- package/dist/calendar/gregory/adapter.d.ts +3 -0
- package/dist/calendar/gregory/adapter.js +93 -0
- package/dist/calendar/gregory/adapter.js.map +1 -0
- package/dist/calendar/gregory/constants.d.ts +3 -0
- package/dist/calendar/gregory/constants.js +18 -0
- package/dist/calendar/gregory/constants.js.map +1 -0
- package/dist/calendar/gregory/index.d.ts +4 -0
- package/dist/calendar/gregory/index.js +5 -0
- package/dist/calendar/gregory/index.js.map +1 -0
- package/dist/calendar/gregory/leap-year.d.ts +1 -0
- package/dist/calendar/gregory/leap-year.js +2 -0
- package/dist/calendar/gregory/leap-year.js.map +1 -0
- package/dist/calendar/gregory/validator.d.ts +2 -0
- package/dist/calendar/gregory/validator.js +45 -0
- package/dist/calendar/gregory/validator.js.map +1 -0
- package/dist/calendar/hijri/civil-adapter.d.ts +12 -0
- package/dist/calendar/hijri/civil-adapter.js +132 -0
- package/dist/calendar/hijri/civil-adapter.js.map +1 -0
- package/dist/calendar/hijri/index.d.ts +3 -0
- package/dist/calendar/hijri/index.js +4 -0
- package/dist/calendar/hijri/index.js.map +1 -0
- package/dist/calendar/hijri/tabular-adapter.d.ts +4 -0
- package/dist/calendar/hijri/tabular-adapter.js +79 -0
- package/dist/calendar/hijri/tabular-adapter.js.map +1 -0
- package/dist/calendar/hijri/umm-al-qura-adapter.d.ts +4 -0
- package/dist/calendar/hijri/umm-al-qura-adapter.js +27 -0
- package/dist/calendar/hijri/umm-al-qura-adapter.js.map +1 -0
- package/dist/calendar/index.d.ts +13 -0
- package/dist/calendar/index.js +12 -0
- package/dist/calendar/index.js.map +1 -0
- package/dist/calendar/indian/adapter.d.ts +2 -0
- package/dist/calendar/indian/adapter.js +66 -0
- package/dist/calendar/indian/adapter.js.map +1 -0
- package/dist/calendar/indian/constants.d.ts +5 -0
- package/dist/calendar/indian/constants.js +43 -0
- package/dist/calendar/indian/constants.js.map +1 -0
- package/dist/calendar/indian/index.d.ts +3 -0
- package/dist/calendar/indian/index.js +4 -0
- package/dist/calendar/indian/index.js.map +1 -0
- package/dist/calendar/indian/validator.d.ts +6 -0
- package/dist/calendar/indian/validator.js +65 -0
- package/dist/calendar/indian/validator.js.map +1 -0
- package/dist/calendar/japanese/adapter.d.ts +3 -0
- package/dist/calendar/japanese/adapter.js +63 -0
- package/dist/calendar/japanese/adapter.js.map +1 -0
- package/dist/calendar/japanese/constants.d.ts +17 -0
- package/dist/calendar/japanese/constants.js +85 -0
- package/dist/calendar/japanese/constants.js.map +1 -0
- package/dist/calendar/japanese/index.d.ts +3 -0
- package/dist/calendar/japanese/index.js +4 -0
- package/dist/calendar/japanese/index.js.map +1 -0
- package/dist/calendar/japanese/validator.d.ts +5 -0
- package/dist/calendar/japanese/validator.js +76 -0
- package/dist/calendar/japanese/validator.js.map +1 -0
- package/dist/calendar/persian/adapter.d.ts +2 -0
- package/dist/calendar/persian/adapter.js +42 -0
- package/dist/calendar/persian/adapter.js.map +1 -0
- package/dist/calendar/persian/constants.d.ts +5 -0
- package/dist/calendar/persian/constants.js +43 -0
- package/dist/calendar/persian/constants.js.map +1 -0
- package/dist/calendar/persian/index.d.ts +4 -0
- package/dist/calendar/persian/index.js +5 -0
- package/dist/calendar/persian/index.js.map +1 -0
- package/dist/calendar/persian/math.d.ts +24 -0
- package/dist/calendar/persian/math.js +109 -0
- package/dist/calendar/persian/math.js.map +1 -0
- package/dist/calendar/persian/validator.d.ts +4 -0
- package/dist/calendar/persian/validator.js +52 -0
- package/dist/calendar/persian/validator.js.map +1 -0
- package/dist/calendar/registry.d.ts +9 -0
- package/dist/calendar/registry.js +119 -0
- package/dist/calendar/registry.js.map +1 -0
- package/dist/calendar/roc/adapter.d.ts +2 -0
- package/dist/calendar/roc/adapter.js +47 -0
- package/dist/calendar/roc/adapter.js.map +1 -0
- package/dist/calendar/roc/constants.d.ts +6 -0
- package/dist/calendar/roc/constants.js +34 -0
- package/dist/calendar/roc/constants.js.map +1 -0
- package/dist/calendar/roc/index.d.ts +3 -0
- package/dist/calendar/roc/index.js +4 -0
- package/dist/calendar/roc/index.js.map +1 -0
- package/dist/calendar/roc/validator.d.ts +4 -0
- package/dist/calendar/roc/validator.js +52 -0
- package/dist/calendar/roc/validator.js.map +1 -0
- package/dist/calendar/types.d.ts +34 -0
- package/dist/calendar/types.js +2 -0
- package/dist/calendar/types.js.map +1 -0
- package/dist/core/absolute-day.d.ts +8 -0
- package/dist/core/absolute-day.js +39 -0
- package/dist/core/absolute-day.js.map +1 -0
- package/dist/core/calendar-date.d.ts +11 -0
- package/dist/core/calendar-date.js +37 -0
- package/dist/core/calendar-date.js.map +1 -0
- package/dist/core/day-of-year.d.ts +16 -0
- package/dist/core/day-of-year.js +30 -0
- package/dist/core/day-of-year.js.map +1 -0
- package/dist/core/duration.d.ts +2 -0
- package/dist/core/duration.js +31 -0
- package/dist/core/duration.js.map +1 -0
- package/dist/core/fiscal.d.ts +31 -0
- package/dist/core/fiscal.js +45 -0
- package/dist/core/fiscal.js.map +1 -0
- package/dist/core/gregorian-math.d.ts +4 -0
- package/dist/core/gregorian-math.js +30 -0
- package/dist/core/gregorian-math.js.map +1 -0
- package/dist/core/instant.d.ts +6 -0
- package/dist/core/instant.js +26 -0
- package/dist/core/instant.js.map +1 -0
- package/dist/core/integer.d.ts +1 -0
- package/dist/core/integer.js +7 -0
- package/dist/core/integer.js.map +1 -0
- package/dist/core/iso-week.d.ts +19 -0
- package/dist/core/iso-week.js +41 -0
- package/dist/core/iso-week.js.map +1 -0
- package/dist/core/julian-day.d.ts +26 -0
- package/dist/core/julian-day.js +35 -0
- package/dist/core/julian-day.js.map +1 -0
- package/dist/core/local-date-time.d.ts +2 -0
- package/dist/core/local-date-time.js +15 -0
- package/dist/core/local-date-time.js.map +1 -0
- package/dist/core/local-date.d.ts +2 -0
- package/dist/core/local-date.js +22 -0
- package/dist/core/local-date.js.map +1 -0
- package/dist/core/local-time.d.ts +2 -0
- package/dist/core/local-time.js +28 -0
- package/dist/core/local-time.js.map +1 -0
- package/dist/core/range.d.ts +2 -0
- package/dist/core/range.js +9 -0
- package/dist/core/range.js.map +1 -0
- package/dist/create-chronera.d.ts +2 -0
- package/dist/create-chronera.js +59 -0
- package/dist/create-chronera.js.map +1 -0
- package/dist/errors/error-codes.d.ts +1 -0
- package/dist/errors/error-codes.js +2 -0
- package/dist/errors/error-codes.js.map +1 -0
- package/dist/errors/errors.d.ts +16 -0
- package/dist/errors/errors.js +22 -0
- package/dist/errors/errors.js.map +1 -0
- package/dist/errors/index.d.ts +2 -0
- package/dist/errors/index.js +2 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/format/format-date-range.d.ts +2 -0
- package/dist/format/format-date-range.js +89 -0
- package/dist/format/format-date-range.js.map +1 -0
- package/dist/format/format-date-time.d.ts +2 -0
- package/dist/format/format-date-time.js +51 -0
- package/dist/format/format-date-time.js.map +1 -0
- package/dist/format/format-date.d.ts +4 -0
- package/dist/format/format-date.js +103 -0
- package/dist/format/format-date.js.map +1 -0
- package/dist/format/format-pattern.d.ts +4 -0
- package/dist/format/format-pattern.js +266 -0
- package/dist/format/format-pattern.js.map +1 -0
- package/dist/format/format-relative.d.ts +2 -0
- package/dist/format/format-relative.js +93 -0
- package/dist/format/format-relative.js.map +1 -0
- package/dist/format/format-time.d.ts +2 -0
- package/dist/format/format-time.js +48 -0
- package/dist/format/format-time.js.map +1 -0
- package/dist/format/index.d.ts +13 -0
- package/dist/format/index.js +12 -0
- package/dist/format/index.js.map +1 -0
- package/dist/format/pattern-scanner.d.ts +8 -0
- package/dist/format/pattern-scanner.js +102 -0
- package/dist/format/pattern-scanner.js.map +1 -0
- package/dist/format/presets/japanese-official.d.ts +8 -0
- package/dist/format/presets/japanese-official.js +39 -0
- package/dist/format/presets/japanese-official.js.map +1 -0
- package/dist/format/presets/taiwan-official.d.ts +6 -0
- package/dist/format/presets/taiwan-official.js +23 -0
- package/dist/format/presets/taiwan-official.js.map +1 -0
- package/dist/format/presets/thai-official.d.ts +2 -0
- package/dist/format/presets/thai-official.js +45 -0
- package/dist/format/presets/thai-official.js.map +1 -0
- package/dist/format/presets/types.d.ts +2 -0
- package/dist/format/presets/types.js +2 -0
- package/dist/format/presets/types.js.map +1 -0
- package/dist/format/presets/world-locales.d.ts +29 -0
- package/dist/format/presets/world-locales.js +330 -0
- package/dist/format/presets/world-locales.js.map +1 -0
- package/dist/format/resolve-date-input.d.ts +9 -0
- package/dist/format/resolve-date-input.js +93 -0
- package/dist/format/resolve-date-input.js.map +1 -0
- package/dist/format/rfc2822.d.ts +17 -0
- package/dist/format/rfc2822.js +59 -0
- package/dist/format/rfc2822.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/engine.d.ts +8 -0
- package/dist/internal/engine.js +11 -0
- package/dist/internal/engine.js.map +1 -0
- package/dist/locale/numbering-system.d.ts +4 -0
- package/dist/locale/numbering-system.js +133 -0
- package/dist/locale/numbering-system.js.map +1 -0
- package/dist/locale/resolve-locale.d.ts +7 -0
- package/dist/locale/resolve-locale.js +51 -0
- package/dist/locale/resolve-locale.js.map +1 -0
- package/dist/locale/types.d.ts +1 -0
- package/dist/locale/types.js +2 -0
- package/dist/locale/types.js.map +1 -0
- package/dist/operations/arithmetic.d.ts +4 -0
- package/dist/operations/arithmetic.js +13 -0
- package/dist/operations/arithmetic.js.map +1 -0
- package/dist/operations/compare.d.ts +5 -0
- package/dist/operations/compare.js +50 -0
- package/dist/operations/compare.js.map +1 -0
- package/dist/operations/convert-calendar-date.d.ts +4 -0
- package/dist/operations/convert-calendar-date.js +54 -0
- package/dist/operations/convert-calendar-date.js.map +1 -0
- package/dist/operations/day-of-year.d.ts +7 -0
- package/dist/operations/day-of-year.js +29 -0
- package/dist/operations/day-of-year.js.map +1 -0
- package/dist/operations/fiscal.d.ts +5 -0
- package/dist/operations/fiscal.js +25 -0
- package/dist/operations/fiscal.js.map +1 -0
- package/dist/operations/iso-week.d.ts +9 -0
- package/dist/operations/iso-week.js +29 -0
- package/dist/operations/iso-week.js.map +1 -0
- package/dist/operations/julian-day.d.ts +6 -0
- package/dist/operations/julian-day.js +37 -0
- package/dist/operations/julian-day.js.map +1 -0
- package/dist/operations/validate.d.ts +10 -0
- package/dist/operations/validate.js +55 -0
- package/dist/operations/validate.js.map +1 -0
- package/dist/parse/field-normalizer.d.ts +1 -0
- package/dist/parse/field-normalizer.js +5 -0
- package/dist/parse/field-normalizer.js.map +1 -0
- package/dist/parse/index.d.ts +4 -0
- package/dist/parse/index.js +4 -0
- package/dist/parse/index.js.map +1 -0
- package/dist/parse/parse-instant.d.ts +2 -0
- package/dist/parse/parse-instant.js +97 -0
- package/dist/parse/parse-instant.js.map +1 -0
- package/dist/parse/parse-local-date.d.ts +2 -0
- package/dist/parse/parse-local-date.js +31 -0
- package/dist/parse/parse-local-date.js.map +1 -0
- package/dist/parse/pattern-parser.d.ts +2 -0
- package/dist/parse/pattern-parser.js +150 -0
- package/dist/parse/pattern-parser.js.map +1 -0
- package/dist/parse/safe-parse.d.ts +3 -0
- package/dist/parse/safe-parse.js +46 -0
- package/dist/parse/safe-parse.js.map +1 -0
- package/dist/public-types.d.ts +209 -0
- package/dist/public-types.js +2 -0
- package/dist/public-types.js.map +1 -0
- package/dist/runtime/bounded-lru.d.ts +11 -0
- package/dist/runtime/bounded-lru.js +42 -0
- package/dist/runtime/bounded-lru.js.map +1 -0
- package/dist/runtime/capabilities.d.ts +5 -0
- package/dist/runtime/capabilities.js +61 -0
- package/dist/runtime/capabilities.js.map +1 -0
- package/dist/runtime/intl-date-time.d.ts +11 -0
- package/dist/runtime/intl-date-time.js +38 -0
- package/dist/runtime/intl-date-time.js.map +1 -0
- package/dist/runtime/intl-number.d.ts +7 -0
- package/dist/runtime/intl-number.js +35 -0
- package/dist/runtime/intl-number.js.map +1 -0
- package/dist/runtime/intl-relative-time.d.ts +7 -0
- package/dist/runtime/intl-relative-time.js +35 -0
- package/dist/runtime/intl-relative-time.js.map +1 -0
- package/dist/runtime/timezone.d.ts +14 -0
- package/dist/runtime/timezone.js +95 -0
- package/dist/runtime/timezone.js.map +1 -0
- package/package.json +155 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ChroneraError } from "../errors/errors.js";
|
|
2
|
+
import { instantFromDate } from "../core/instant.js";
|
|
3
|
+
import { validateAndResolveLocale } from "../locale/resolve-locale.js";
|
|
4
|
+
import { formatNumberWithSystem } from "../locale/numbering-system.js";
|
|
5
|
+
export function formatDateTime(input, options = {}) {
|
|
6
|
+
const localeInfo = validateAndResolveLocale(options.locale);
|
|
7
|
+
const locale = localeInfo.baseLocale;
|
|
8
|
+
const numberingSystem = options.numberingSystem ?? localeInfo.unicodeNumberingSystem;
|
|
9
|
+
const dateStyle = options.dateStyle ?? "medium";
|
|
10
|
+
const timeStyle = options.timeStyle ?? "short";
|
|
11
|
+
const calId = options.calendar ?? "gregory";
|
|
12
|
+
let timestamp;
|
|
13
|
+
let timeZone = "UTC";
|
|
14
|
+
if ("kind" in input && input.kind === "local-date-time") {
|
|
15
|
+
if (options.timeZone !== undefined) {
|
|
16
|
+
throw new ChroneraError("CHRONERA_INCOMPATIBLE_OPTION", "Timezone option is forbidden for local-date-time inputs.");
|
|
17
|
+
}
|
|
18
|
+
timestamp = Date.UTC(input.date.year, input.date.month - 1, input.date.day, input.time.hour, input.time.minute, input.time.second, input.time.millisecond);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
let instant;
|
|
22
|
+
if ("kind" in input && input.kind === "instant") {
|
|
23
|
+
instant = input;
|
|
24
|
+
}
|
|
25
|
+
else if (input instanceof Date) {
|
|
26
|
+
instant = instantFromDate(input);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
throw new ChroneraError("CHRONERA_INVALID_DATE", "Expected LocalDateTime, Instant, or Date.");
|
|
30
|
+
}
|
|
31
|
+
timestamp = instant.epochMilliseconds;
|
|
32
|
+
timeZone = options.timeZone ?? "UTC";
|
|
33
|
+
}
|
|
34
|
+
const intlOpts = {
|
|
35
|
+
dateStyle,
|
|
36
|
+
timeStyle,
|
|
37
|
+
timeZone,
|
|
38
|
+
...(calId !== "iso8601" ? { calendar: calId } : { calendar: "gregory" }),
|
|
39
|
+
...(options.hourCycle !== undefined
|
|
40
|
+
? { hourCycle: options.hourCycle }
|
|
41
|
+
: {}),
|
|
42
|
+
...(numberingSystem !== undefined ? { numberingSystem } : {}),
|
|
43
|
+
};
|
|
44
|
+
const dtf = new Intl.DateTimeFormat(locale, intlOpts);
|
|
45
|
+
let output = dtf.format(new Date(timestamp));
|
|
46
|
+
if (numberingSystem && numberingSystem !== "latn") {
|
|
47
|
+
output = formatNumberWithSystem(output, numberingSystem);
|
|
48
|
+
}
|
|
49
|
+
return output;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=format-date-time.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-date-time.js","sourceRoot":"","sources":["../../src/format/format-date-time.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChroneraError } from \"../errors/errors.js\";\nimport { instantFromDate } from \"../core/instant.js\";\nimport { validateAndResolveLocale } from \"../locale/resolve-locale.js\";\nimport { formatNumberWithSystem } from \"../locale/numbering-system.js\";\n\nimport type {\n FormatDateTimeOptions,\n Instant,\n LocalDateTime,\n} from \"../public-types.js\";\n\nexport function formatDateTime(\n input: LocalDateTime | Instant | Date,\n options: Readonly<FormatDateTimeOptions> = {},\n): string {\n const localeInfo = validateAndResolveLocale(options.locale);\n const locale = localeInfo.baseLocale;\n const numberingSystem =\n options.numberingSystem ?? localeInfo.unicodeNumberingSystem;\n const dateStyle = options.dateStyle ?? \"medium\";\n const timeStyle = options.timeStyle ?? \"short\";\n const calId = options.calendar ?? \"gregory\";\n\n let timestamp: number;\n let timeZone = \"UTC\";\n\n if (\"kind\" in input && input.kind === \"local-date-time\") {\n if (options.timeZone !== undefined) {\n throw new ChroneraError(\n \"CHRONERA_INCOMPATIBLE_OPTION\",\n \"Timezone option is forbidden for local-date-time inputs.\",\n );\n }\n timestamp = Date.UTC(\n input.date.year,\n input.date.month - 1,\n input.date.day,\n input.time.hour,\n input.time.minute,\n input.time.second,\n input.time.millisecond,\n );\n } else {\n let instant: Instant;\n if (\"kind\" in input && input.kind === \"instant\") {\n instant = input;\n } else if (input instanceof Date) {\n instant = instantFromDate(input);\n } else {\n throw new ChroneraError(\n \"CHRONERA_INVALID_DATE\",\n \"Expected LocalDateTime, Instant, or Date.\",\n );\n }\n timestamp = instant.epochMilliseconds;\n timeZone = options.timeZone ?? \"UTC\";\n }\n\n const intlOpts: Intl.DateTimeFormatOptions = {\n dateStyle,\n timeStyle,\n timeZone,\n ...(calId !== \"iso8601\" ? { calendar: calId } : { calendar: \"gregory\" }),\n ...(options.hourCycle !== undefined\n ? { hourCycle: options.hourCycle }\n : {}),\n ...(numberingSystem !== undefined ? { numberingSystem } : {}),\n };\n\n const dtf = new Intl.DateTimeFormat(locale, intlOpts);\n let output = dtf.format(new Date(timestamp));\n\n if (numberingSystem && numberingSystem !== \"latn\") {\n output = formatNumberWithSystem(output, numberingSystem);\n }\n\n return output;\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CalendarRegistry } from "../calendar/registry.js";
|
|
2
|
+
import type { FormatDateInput, FormatDateOptions } from "../public-types.js";
|
|
3
|
+
export declare function formatDateWithRegistry(registry: CalendarRegistry, input: FormatDateInput, options?: Readonly<FormatDateOptions>): string;
|
|
4
|
+
export declare function formatDate(input: FormatDateInput, options?: Readonly<FormatDateOptions>): string;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { resolveDateFormattingInput } from "./resolve-date-input.js";
|
|
2
|
+
import { formatThaiOfficialPreset } from "./presets/thai-official.js";
|
|
3
|
+
import { formatJapaneseOfficialPreset, formatJapaneseOfficialWithWeekdayPreset, } from "./presets/japanese-official.js";
|
|
4
|
+
import { formatTaiwanOfficialPreset } from "./presets/taiwan-official.js";
|
|
5
|
+
import { formatArabicGregorianPreset, formatArabicHijriPreset, formatChineseShortPreset, formatChineseStandardPreset, formatChineseWithWeekdayPreset, formatFrenchLongPreset, formatFrenchStandardPreset, formatFrenchWithWeekdayPreset, formatGermanDinStandardPreset, formatGermanLongPreset, formatGermanWithWeekdayPreset, formatJapaneseEraShortPreset, formatJapaneseSeirekiPreset, formatSpanishLongPreset, formatSpanishStandardPreset, formatSpanishWithWeekdayPreset, formatThaiShortDatePreset, formatThaiSlashDatePreset, formatUkLongPreset, formatUkStandardPreset, formatUkWithWeekdayPreset, formatUsLongPreset, formatUsStandardPreset, formatUsWithWeekdayPreset, } from "./presets/world-locales.js";
|
|
6
|
+
import { defaultCalendarRegistry } from "../calendar/registry.js";
|
|
7
|
+
import { validateAndResolveLocale } from "../locale/resolve-locale.js";
|
|
8
|
+
import { formatNumberWithSystem } from "../locale/numbering-system.js";
|
|
9
|
+
import { gregorianFieldsFromAbsoluteDay } from "../core/absolute-day.js";
|
|
10
|
+
export function formatDateWithRegistry(registry, input, options = {}) {
|
|
11
|
+
const resolved = resolveDateFormattingInput(registry, input, options);
|
|
12
|
+
const localeInfo = validateAndResolveLocale(options.locale);
|
|
13
|
+
const locale = localeInfo.baseLocale;
|
|
14
|
+
const numberingSystem = options.numberingSystem ?? localeInfo.unicodeNumberingSystem;
|
|
15
|
+
if (options.preset !== undefined) {
|
|
16
|
+
const presetOpt = numberingSystem !== undefined ? { numberingSystem } : {};
|
|
17
|
+
switch (options.preset) {
|
|
18
|
+
case "thai-official-date":
|
|
19
|
+
case "thai-official-date-with-weekday":
|
|
20
|
+
return formatThaiOfficialPreset(resolved.calendarDate, options.preset, resolved.absoluteDay, numberingSystem ?? "latn");
|
|
21
|
+
case "thai-short-date":
|
|
22
|
+
return formatThaiShortDatePreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
23
|
+
case "thai-slash-date":
|
|
24
|
+
return formatThaiSlashDatePreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
25
|
+
case "japanese-official":
|
|
26
|
+
return formatJapaneseOfficialPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
27
|
+
case "japanese-official-with-weekday":
|
|
28
|
+
return formatJapaneseOfficialWithWeekdayPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
29
|
+
case "japanese-seireki":
|
|
30
|
+
return formatJapaneseSeirekiPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
31
|
+
case "japanese-era-short":
|
|
32
|
+
return formatJapaneseEraShortPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
33
|
+
case "taiwan-official":
|
|
34
|
+
return formatTaiwanOfficialPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
35
|
+
case "us-standard":
|
|
36
|
+
return formatUsStandardPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
37
|
+
case "us-long":
|
|
38
|
+
return formatUsLongPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
39
|
+
case "us-with-weekday":
|
|
40
|
+
return formatUsWithWeekdayPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
41
|
+
case "uk-standard":
|
|
42
|
+
return formatUkStandardPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
43
|
+
case "uk-long":
|
|
44
|
+
return formatUkLongPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
45
|
+
case "uk-with-weekday":
|
|
46
|
+
return formatUkWithWeekdayPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
47
|
+
case "german-din-standard":
|
|
48
|
+
return formatGermanDinStandardPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
49
|
+
case "german-long":
|
|
50
|
+
return formatGermanLongPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
51
|
+
case "german-with-weekday":
|
|
52
|
+
return formatGermanWithWeekdayPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
53
|
+
case "french-standard":
|
|
54
|
+
return formatFrenchStandardPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
55
|
+
case "french-long":
|
|
56
|
+
return formatFrenchLongPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
57
|
+
case "french-with-weekday":
|
|
58
|
+
return formatFrenchWithWeekdayPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
59
|
+
case "chinese-standard":
|
|
60
|
+
return formatChineseStandardPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
61
|
+
case "chinese-with-weekday":
|
|
62
|
+
return formatChineseWithWeekdayPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
63
|
+
case "chinese-short":
|
|
64
|
+
return formatChineseShortPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
65
|
+
case "spanish-standard":
|
|
66
|
+
return formatSpanishStandardPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
67
|
+
case "spanish-long":
|
|
68
|
+
return formatSpanishLongPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
69
|
+
case "spanish-with-weekday":
|
|
70
|
+
return formatSpanishWithWeekdayPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
71
|
+
case "arabic-gregorian":
|
|
72
|
+
return formatArabicGregorianPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
73
|
+
case "arabic-hijri":
|
|
74
|
+
return formatArabicHijriPreset(resolved.calendarDate, resolved.absoluteDay, presetOpt);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const style = options.style ?? "medium";
|
|
78
|
+
const calId = resolved.calendarDate.calendar;
|
|
79
|
+
// Use UTC instant for the Gregorian equivalent day
|
|
80
|
+
const fields = gregorianFieldsFromAbsoluteDay(resolved.absoluteDay);
|
|
81
|
+
const utcDate = new Date(Date.UTC(fields.year, fields.month - 1, fields.day, 12, 0, 0));
|
|
82
|
+
const formatterOptions = {
|
|
83
|
+
timeZone: "UTC",
|
|
84
|
+
...(style === "numeric"
|
|
85
|
+
? { year: "numeric", month: "numeric", day: "numeric" }
|
|
86
|
+
: { dateStyle: style }),
|
|
87
|
+
};
|
|
88
|
+
if (calId !== "gregory" && calId !== "iso8601") {
|
|
89
|
+
formatterOptions.calendar = calId;
|
|
90
|
+
}
|
|
91
|
+
if (numberingSystem) {
|
|
92
|
+
formatterOptions.numberingSystem = numberingSystem;
|
|
93
|
+
}
|
|
94
|
+
const formatted = new Intl.DateTimeFormat(locale, formatterOptions).format(utcDate);
|
|
95
|
+
if (numberingSystem && numberingSystem !== "latn") {
|
|
96
|
+
return formatNumberWithSystem(formatted, numberingSystem);
|
|
97
|
+
}
|
|
98
|
+
return formatted;
|
|
99
|
+
}
|
|
100
|
+
export function formatDate(input, options = {}) {
|
|
101
|
+
return formatDateWithRegistry(defaultCalendarRegistry, input, options);
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=format-date.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-date.js","sourceRoot":"","sources":["../../src/format/format-date.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolveDateFormattingInput } from \"./resolve-date-input.js\";\nimport { formatThaiOfficialPreset } from \"./presets/thai-official.js\";\nimport {\n formatJapaneseOfficialPreset,\n formatJapaneseOfficialWithWeekdayPreset,\n} from \"./presets/japanese-official.js\";\nimport { formatTaiwanOfficialPreset } from \"./presets/taiwan-official.js\";\nimport {\n formatArabicGregorianPreset,\n formatArabicHijriPreset,\n formatChineseShortPreset,\n formatChineseStandardPreset,\n formatChineseWithWeekdayPreset,\n formatFrenchLongPreset,\n formatFrenchStandardPreset,\n formatFrenchWithWeekdayPreset,\n formatGermanDinStandardPreset,\n formatGermanLongPreset,\n formatGermanWithWeekdayPreset,\n formatJapaneseEraShortPreset,\n formatJapaneseSeirekiPreset,\n formatSpanishLongPreset,\n formatSpanishStandardPreset,\n formatSpanishWithWeekdayPreset,\n formatThaiShortDatePreset,\n formatThaiSlashDatePreset,\n formatUkLongPreset,\n formatUkStandardPreset,\n formatUkWithWeekdayPreset,\n formatUsLongPreset,\n formatUsStandardPreset,\n formatUsWithWeekdayPreset,\n} from \"./presets/world-locales.js\";\nimport { defaultCalendarRegistry } from \"../calendar/registry.js\";\nimport { validateAndResolveLocale } from \"../locale/resolve-locale.js\";\nimport { formatNumberWithSystem } from \"../locale/numbering-system.js\";\nimport { gregorianFieldsFromAbsoluteDay } from \"../core/absolute-day.js\";\n\nimport type { CalendarRegistry } from \"../calendar/registry.js\";\nimport type { FormatDateInput, FormatDateOptions } from \"../public-types.js\";\n\nexport function formatDateWithRegistry(\n registry: CalendarRegistry,\n input: FormatDateInput,\n options: Readonly<FormatDateOptions> = {},\n): string {\n const resolved = resolveDateFormattingInput(registry, input, options);\n const localeInfo = validateAndResolveLocale(options.locale);\n const locale = localeInfo.baseLocale;\n const numberingSystem =\n options.numberingSystem ?? localeInfo.unicodeNumberingSystem;\n\n if (options.preset !== undefined) {\n const presetOpt = numberingSystem !== undefined ? { numberingSystem } : {};\n switch (options.preset) {\n case \"thai-official-date\":\n case \"thai-official-date-with-weekday\":\n return formatThaiOfficialPreset(\n resolved.calendarDate,\n options.preset,\n resolved.absoluteDay,\n numberingSystem ?? \"latn\",\n );\n case \"thai-short-date\":\n return formatThaiShortDatePreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"thai-slash-date\":\n return formatThaiSlashDatePreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"japanese-official\":\n return formatJapaneseOfficialPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"japanese-official-with-weekday\":\n return formatJapaneseOfficialWithWeekdayPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"japanese-seireki\":\n return formatJapaneseSeirekiPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"japanese-era-short\":\n return formatJapaneseEraShortPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"taiwan-official\":\n return formatTaiwanOfficialPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"us-standard\":\n return formatUsStandardPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"us-long\":\n return formatUsLongPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"us-with-weekday\":\n return formatUsWithWeekdayPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"uk-standard\":\n return formatUkStandardPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"uk-long\":\n return formatUkLongPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"uk-with-weekday\":\n return formatUkWithWeekdayPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"german-din-standard\":\n return formatGermanDinStandardPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"german-long\":\n return formatGermanLongPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"german-with-weekday\":\n return formatGermanWithWeekdayPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"french-standard\":\n return formatFrenchStandardPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"french-long\":\n return formatFrenchLongPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"french-with-weekday\":\n return formatFrenchWithWeekdayPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"chinese-standard\":\n return formatChineseStandardPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"chinese-with-weekday\":\n return formatChineseWithWeekdayPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"chinese-short\":\n return formatChineseShortPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"spanish-standard\":\n return formatSpanishStandardPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"spanish-long\":\n return formatSpanishLongPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"spanish-with-weekday\":\n return formatSpanishWithWeekdayPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"arabic-gregorian\":\n return formatArabicGregorianPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n case \"arabic-hijri\":\n return formatArabicHijriPreset(\n resolved.calendarDate,\n resolved.absoluteDay,\n presetOpt,\n );\n }\n }\n\n const style = options.style ?? \"medium\";\n const calId = resolved.calendarDate.calendar;\n\n // Use UTC instant for the Gregorian equivalent day\n const fields = gregorianFieldsFromAbsoluteDay(resolved.absoluteDay);\n const utcDate = new Date(\n Date.UTC(fields.year, fields.month - 1, fields.day, 12, 0, 0),\n );\n\n const formatterOptions: Intl.DateTimeFormatOptions = {\n timeZone: \"UTC\",\n ...(style === \"numeric\"\n ? { year: \"numeric\", month: \"numeric\", day: \"numeric\" }\n : { dateStyle: style }),\n };\n\n if (calId !== \"gregory\" && calId !== \"iso8601\") {\n formatterOptions.calendar = calId;\n }\n\n if (numberingSystem) {\n formatterOptions.numberingSystem = numberingSystem;\n }\n\n const formatted = new Intl.DateTimeFormat(locale, formatterOptions).format(\n utcDate,\n );\n\n if (numberingSystem && numberingSystem !== \"latn\") {\n return formatNumberWithSystem(formatted, numberingSystem);\n }\n\n return formatted;\n}\n\nexport function formatDate(\n input: FormatDateInput,\n options: Readonly<FormatDateOptions> = {},\n): string {\n return formatDateWithRegistry(defaultCalendarRegistry, input, options);\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CalendarRegistry } from "../calendar/registry.js";
|
|
2
|
+
import type { FormatDateInput, LocalDateTime, PatternFormatOptions } from "../public-types.js";
|
|
3
|
+
export declare function formatWithPatternWithRegistry(registry: CalendarRegistry, input: FormatDateInput | LocalDateTime, pattern: string, options?: Readonly<PatternFormatOptions>): string;
|
|
4
|
+
export declare function formatWithPattern(input: FormatDateInput | LocalDateTime, pattern: string, options?: Readonly<PatternFormatOptions>): string;
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { scanPattern } from "./pattern-scanner.js";
|
|
2
|
+
import { formatNumberWithSystem } from "../locale/numbering-system.js";
|
|
3
|
+
import { resolveDateFormattingInput } from "./resolve-date-input.js";
|
|
4
|
+
import { defaultCalendarRegistry } from "../calendar/registry.js";
|
|
5
|
+
import { validateAndResolveLocale } from "../locale/resolve-locale.js";
|
|
6
|
+
import { absoluteDayFromGregorianFields } from "../core/absolute-day.js";
|
|
7
|
+
import { getDayOfYearFromAbsoluteDay } from "../core/day-of-year.js";
|
|
8
|
+
import { getIsoDayOfWeek, getIsoWeekFromAbsoluteDay, } from "../core/iso-week.js";
|
|
9
|
+
import { ChroneraError } from "../errors/errors.js";
|
|
10
|
+
export function formatWithPatternWithRegistry(registry, input, pattern, options = {}) {
|
|
11
|
+
const tokens = scanPattern(pattern);
|
|
12
|
+
const localeInfo = validateAndResolveLocale(options.locale);
|
|
13
|
+
const locale = localeInfo.baseLocale;
|
|
14
|
+
const numberingSystem = options.numberingSystem ?? "latn";
|
|
15
|
+
// Check if input is LocalDateTime
|
|
16
|
+
let isLocalDateTime = false;
|
|
17
|
+
let localDt;
|
|
18
|
+
if ("kind" in input && input.kind === "local-date-time") {
|
|
19
|
+
isLocalDateTime = true;
|
|
20
|
+
localDt = input;
|
|
21
|
+
}
|
|
22
|
+
let calDate;
|
|
23
|
+
let absDay;
|
|
24
|
+
let hour = 0;
|
|
25
|
+
let minute = 0;
|
|
26
|
+
let second = 0;
|
|
27
|
+
let millisecond = 0;
|
|
28
|
+
let offsetString = "Z";
|
|
29
|
+
if (isLocalDateTime && localDt) {
|
|
30
|
+
calDate = {
|
|
31
|
+
kind: "calendar-date",
|
|
32
|
+
calendar: "gregory",
|
|
33
|
+
year: localDt.date.year,
|
|
34
|
+
monthCode: `M${String(localDt.date.month).padStart(2, "0")}`,
|
|
35
|
+
month: localDt.date.month,
|
|
36
|
+
day: localDt.date.day,
|
|
37
|
+
era: "CE",
|
|
38
|
+
eraYear: localDt.date.year,
|
|
39
|
+
};
|
|
40
|
+
absDay = absoluteDayFromGregorianFields(localDt.date.year, localDt.date.month, localDt.date.day);
|
|
41
|
+
hour = localDt.time.hour;
|
|
42
|
+
minute = localDt.time.minute;
|
|
43
|
+
second = localDt.time.second;
|
|
44
|
+
millisecond = localDt.time.millisecond;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
const resolved = resolveDateFormattingInput(registry, input, options);
|
|
48
|
+
calDate = resolved.calendarDate;
|
|
49
|
+
absDay = resolved.absoluteDay;
|
|
50
|
+
if (resolved.instant) {
|
|
51
|
+
const date = new Date(resolved.instant.epochMilliseconds);
|
|
52
|
+
const tz = resolved.timeZone ?? "UTC";
|
|
53
|
+
// Project fields using Intl
|
|
54
|
+
const dtf = new Intl.DateTimeFormat("en-US", {
|
|
55
|
+
timeZone: tz,
|
|
56
|
+
hourCycle: "h23",
|
|
57
|
+
hour: "numeric",
|
|
58
|
+
minute: "numeric",
|
|
59
|
+
second: "numeric",
|
|
60
|
+
timeZoneName: "longOffset",
|
|
61
|
+
});
|
|
62
|
+
const parts = dtf.formatToParts(date);
|
|
63
|
+
for (const p of parts) {
|
|
64
|
+
if (p.type === "hour")
|
|
65
|
+
hour = Number.parseInt(p.value, 10);
|
|
66
|
+
if (p.type === "minute")
|
|
67
|
+
minute = Number.parseInt(p.value, 10);
|
|
68
|
+
if (p.type === "second")
|
|
69
|
+
second = Number.parseInt(p.value, 10);
|
|
70
|
+
if (p.type === "timeZoneName") {
|
|
71
|
+
// e.g. "GMT+07:00" -> "+07:00"
|
|
72
|
+
const m = p.value.match(/GMT([+-]\d{2}:\d{2})/);
|
|
73
|
+
if (m && m[1]) {
|
|
74
|
+
offsetString = m[1];
|
|
75
|
+
}
|
|
76
|
+
else if (p.value === "GMT") {
|
|
77
|
+
offsetString = "Z";
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
millisecond = ((resolved.instant.epochMilliseconds % 1000) + 1000) % 1000;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const month = calDate.month ?? Number.parseInt(calDate.monthCode.slice(1), 10);
|
|
85
|
+
const year = calDate.eraYear ?? calDate.year;
|
|
86
|
+
// Helper for localized text
|
|
87
|
+
const localizedDate = new Date(Date.UTC(calDate.year, month - 1, calDate.day));
|
|
88
|
+
let out = "";
|
|
89
|
+
for (const t of tokens) {
|
|
90
|
+
if (t.type === "literal") {
|
|
91
|
+
out += t.value;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
switch (t.symbol) {
|
|
95
|
+
case "y":
|
|
96
|
+
out += formatNumberWithSystem(year, numberingSystem);
|
|
97
|
+
break;
|
|
98
|
+
case "yy":
|
|
99
|
+
out += formatNumberWithSystem(String(year % 100).padStart(2, "0"), numberingSystem);
|
|
100
|
+
break;
|
|
101
|
+
case "yyyy":
|
|
102
|
+
out += formatNumberWithSystem(String(year).padStart(4, "0"), numberingSystem);
|
|
103
|
+
break;
|
|
104
|
+
case "M":
|
|
105
|
+
out += formatNumberWithSystem(month, numberingSystem);
|
|
106
|
+
break;
|
|
107
|
+
case "MM":
|
|
108
|
+
out += formatNumberWithSystem(String(month).padStart(2, "0"), numberingSystem);
|
|
109
|
+
break;
|
|
110
|
+
case "MMM": {
|
|
111
|
+
const dtf = new Intl.DateTimeFormat(locale, {
|
|
112
|
+
calendar: calDate.calendar,
|
|
113
|
+
month: "short",
|
|
114
|
+
timeZone: "UTC",
|
|
115
|
+
});
|
|
116
|
+
out += dtf.format(localizedDate);
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
case "MMMM": {
|
|
120
|
+
const dtf = new Intl.DateTimeFormat(locale, {
|
|
121
|
+
calendar: calDate.calendar,
|
|
122
|
+
month: "long",
|
|
123
|
+
timeZone: "UTC",
|
|
124
|
+
});
|
|
125
|
+
out += dtf.format(localizedDate);
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
case "d":
|
|
129
|
+
out += formatNumberWithSystem(calDate.day, numberingSystem);
|
|
130
|
+
break;
|
|
131
|
+
case "dd":
|
|
132
|
+
out += formatNumberWithSystem(String(calDate.day).padStart(2, "0"), numberingSystem);
|
|
133
|
+
break;
|
|
134
|
+
case "E": {
|
|
135
|
+
const dtf = new Intl.DateTimeFormat(locale, {
|
|
136
|
+
calendar: calDate.calendar,
|
|
137
|
+
weekday: "short",
|
|
138
|
+
timeZone: "UTC",
|
|
139
|
+
});
|
|
140
|
+
out += dtf.format(localizedDate);
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
case "EEEE": {
|
|
144
|
+
const dtf = new Intl.DateTimeFormat(locale, {
|
|
145
|
+
calendar: calDate.calendar,
|
|
146
|
+
weekday: "long",
|
|
147
|
+
timeZone: "UTC",
|
|
148
|
+
});
|
|
149
|
+
out += dtf.format(localizedDate);
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
case "G":
|
|
153
|
+
out += calDate.era ?? (year >= 0 ? "AD" : "BC");
|
|
154
|
+
break;
|
|
155
|
+
case "GGGG": {
|
|
156
|
+
const dtf = new Intl.DateTimeFormat(locale, {
|
|
157
|
+
calendar: calDate.calendar,
|
|
158
|
+
era: "long",
|
|
159
|
+
timeZone: "UTC",
|
|
160
|
+
});
|
|
161
|
+
out += dtf.format(localizedDate);
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
case "H":
|
|
165
|
+
out += formatNumberWithSystem(hour, numberingSystem);
|
|
166
|
+
break;
|
|
167
|
+
case "HH":
|
|
168
|
+
out += formatNumberWithSystem(String(hour).padStart(2, "0"), numberingSystem);
|
|
169
|
+
break;
|
|
170
|
+
case "h": {
|
|
171
|
+
const h12 = hour % 12 === 0 ? 12 : hour % 12;
|
|
172
|
+
out += formatNumberWithSystem(h12, numberingSystem);
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
case "hh": {
|
|
176
|
+
const h12 = hour % 12 === 0 ? 12 : hour % 12;
|
|
177
|
+
out += formatNumberWithSystem(String(h12).padStart(2, "0"), numberingSystem);
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
case "a":
|
|
181
|
+
out += hour < 12 ? "AM" : "PM";
|
|
182
|
+
break;
|
|
183
|
+
case "m":
|
|
184
|
+
out += formatNumberWithSystem(minute, numberingSystem);
|
|
185
|
+
break;
|
|
186
|
+
case "mm":
|
|
187
|
+
out += formatNumberWithSystem(String(minute).padStart(2, "0"), numberingSystem);
|
|
188
|
+
break;
|
|
189
|
+
case "s":
|
|
190
|
+
out += formatNumberWithSystem(second, numberingSystem);
|
|
191
|
+
break;
|
|
192
|
+
case "ss":
|
|
193
|
+
out += formatNumberWithSystem(String(second).padStart(2, "0"), numberingSystem);
|
|
194
|
+
break;
|
|
195
|
+
case "S": {
|
|
196
|
+
const frac1 = Math.floor(millisecond / 100);
|
|
197
|
+
out += formatNumberWithSystem(frac1, numberingSystem);
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
case "SSS":
|
|
201
|
+
out += formatNumberWithSystem(String(millisecond).padStart(3, "0"), numberingSystem);
|
|
202
|
+
break;
|
|
203
|
+
case "XXX":
|
|
204
|
+
out += offsetString === "+00:00" ? "Z" : offsetString;
|
|
205
|
+
break;
|
|
206
|
+
case "Q": {
|
|
207
|
+
const qNum = Math.floor((month - 1) / 3) + 1;
|
|
208
|
+
out += formatNumberWithSystem(qNum, numberingSystem);
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
case "QQQ": {
|
|
212
|
+
const qNum = Math.floor((month - 1) / 3) + 1;
|
|
213
|
+
out += `Q${formatNumberWithSystem(qNum, numberingSystem)}`;
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
case "QQQQ": {
|
|
217
|
+
const qIndex = Math.floor((month - 1) / 3);
|
|
218
|
+
const qNames = [
|
|
219
|
+
"1st quarter",
|
|
220
|
+
"2nd quarter",
|
|
221
|
+
"3rd quarter",
|
|
222
|
+
"4th quarter",
|
|
223
|
+
];
|
|
224
|
+
out += qNames[qIndex];
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
case "D": {
|
|
228
|
+
const doy = getDayOfYearFromAbsoluteDay(absDay).dayOfYear;
|
|
229
|
+
out += formatNumberWithSystem(doy, numberingSystem);
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
case "DDD": {
|
|
233
|
+
const doy = getDayOfYearFromAbsoluteDay(absDay).dayOfYear;
|
|
234
|
+
out += formatNumberWithSystem(String(doy).padStart(3, "0"), numberingSystem);
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
case "w": {
|
|
238
|
+
const wn = getIsoWeekFromAbsoluteDay(absDay).weekNumber;
|
|
239
|
+
out += formatNumberWithSystem(wn, numberingSystem);
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
case "ww": {
|
|
243
|
+
const wn = getIsoWeekFromAbsoluteDay(absDay).weekNumber;
|
|
244
|
+
out += formatNumberWithSystem(String(wn).padStart(2, "0"), numberingSystem);
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
case "e": {
|
|
248
|
+
const dow = getIsoDayOfWeek(absDay);
|
|
249
|
+
out += formatNumberWithSystem(dow, numberingSystem);
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
case "ee": {
|
|
253
|
+
const dow = getIsoDayOfWeek(absDay);
|
|
254
|
+
out += formatNumberWithSystem(String(dow).padStart(2, "0"), numberingSystem);
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
default:
|
|
258
|
+
throw new ChroneraError("CHRONERA_PATTERN_TOO_COMPLEX", `Unhandled pattern symbol: ${t.symbol}`);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return out;
|
|
262
|
+
}
|
|
263
|
+
export function formatWithPattern(input, pattern, options) {
|
|
264
|
+
return formatWithPatternWithRegistry(defaultCalendarRegistry, input, pattern, options);
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=format-pattern.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-pattern.js","sourceRoot":"","sources":["../../src/format/format-pattern.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EACL,eAAe,EACf,yBAAyB,GAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAUpD,MAAM,UAAU,6BAA6B,CAC3C,QAA0B,EAC1B,KAAsC,EACtC,OAAe,EACf,UAA0C,EAAE;IAE5C,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACpC,MAAM,UAAU,GAAG,wBAAwB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC;IACrC,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,MAAM,CAAC;IAE1D,kCAAkC;IAClC,IAAI,eAAe,GAAG,KAAK,CAAC;IAC5B,IAAI,OAAkC,CAAC;IACvC,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;QACxD,eAAe,GAAG,IAAI,CAAC;QACvB,OAAO,GAAG,KAAK,CAAC;IAClB,CAAC;IAED,IAAI,OAAqB,CAAC;IAC1B,IAAI,MAAc,CAAC;IACnB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,YAAY,GAAG,GAAG,CAAC;IAEvB,IAAI,eAAe,IAAI,OAAO,EAAE,CAAC;QAC/B,OAAO,GAAG;YACR,IAAI,EAAE,eAAe;YACrB,QAAQ,EAAE,SAAS;YACnB,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI;YACvB,SAAS,EAAE,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;YAC5D,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK;YACzB,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG;YACrB,GAAG,EAAE,IAAI;YACT,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI;SAC3B,CAAC;QACF,MAAM,GAAG,8BAA8B,CACrC,OAAO,CAAC,IAAI,CAAC,IAAI,EACjB,OAAO,CAAC,IAAI,CAAC,KAAK,EAClB,OAAO,CAAC,IAAI,CAAC,GAAG,CACjB,CAAC;QACF,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;QACzB,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;QAC7B,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;QAC7B,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC;IACzC,CAAC;SAAM,CAAC;QACN,MAAM,QAAQ,GAAG,0BAA0B,CACzC,QAAQ,EACR,KAAwB,EACxB,OAAO,CACR,CAAC;QACF,OAAO,GAAG,QAAQ,CAAC,YAAY,CAAC;QAChC,MAAM,GAAG,QAAQ,CAAC,WAAW,CAAC;QAE9B,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;YAC1D,MAAM,EAAE,GAAG,QAAQ,CAAC,QAAQ,IAAI,KAAK,CAAC;YAEtC,4BAA4B;YAC5B,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE;gBAC3C,QAAQ,EAAE,EAAE;gBACZ,SAAS,EAAE,KAAK;gBAChB,IAAI,EAAE,SAAS;gBACf,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,SAAS;gBACjB,YAAY,EAAE,YAAY;aAC3B,CAAC,CAAC;YAEH,MAAM,KAAK,GAAG,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YACtC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;oBAAE,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBAC3D,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ;oBAAE,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBAC/D,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ;oBAAE,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBAC/D,IAAI,CAAC,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;oBAC9B,+BAA+B;oBAC/B,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;oBAChD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;wBACd,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;oBACtB,CAAC;yBAAM,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;wBAC7B,YAAY,GAAG,GAAG,CAAC;oBACrB,CAAC;gBACH,CAAC;YACH,CAAC;YACD,WAAW,GAAG,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;QAC5E,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GACT,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACnE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAE7C,4BAA4B;IAC5B,MAAM,aAAa,GAAG,IAAI,IAAI,CAC5B,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,CAC/C,CAAC;IAEF,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACzB,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC;YACf,SAAS;QACX,CAAC;QAED,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC;YACjB,KAAK,GAAG;gBACN,GAAG,IAAI,sBAAsB,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;gBACrD,MAAM;YACR,KAAK,IAAI;gBACP,GAAG,IAAI,sBAAsB,CAC3B,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EACnC,eAAe,CAChB,CAAC;gBACF,MAAM;YACR,KAAK,MAAM;gBACT,GAAG,IAAI,sBAAsB,CAC3B,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAC7B,eAAe,CAChB,CAAC;gBACF,MAAM;YACR,KAAK,GAAG;gBACN,GAAG,IAAI,sBAAsB,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;gBACtD,MAAM;YACR,KAAK,IAAI;gBACP,GAAG,IAAI,sBAAsB,CAC3B,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAC9B,eAAe,CAChB,CAAC;gBACF,MAAM;YACR,KAAK,KAAK,CAAC,CAAC,CAAC;gBACX,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE;oBAC1C,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,KAAK,EAAE,OAAO;oBACd,QAAQ,EAAE,KAAK;iBAChB,CAAC,CAAC;gBACH,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;gBACjC,MAAM;YACR,CAAC;YACD,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE;oBAC1C,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,KAAK,EAAE,MAAM;oBACb,QAAQ,EAAE,KAAK;iBAChB,CAAC,CAAC;gBACH,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;gBACjC,MAAM;YACR,CAAC;YACD,KAAK,GAAG;gBACN,GAAG,IAAI,sBAAsB,CAAC,OAAO,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;gBAC5D,MAAM;YACR,KAAK,IAAI;gBACP,GAAG,IAAI,sBAAsB,CAC3B,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EACpC,eAAe,CAChB,CAAC;gBACF,MAAM;YACR,KAAK,GAAG,CAAC,CAAC,CAAC;gBACT,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE;oBAC1C,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,OAAO,EAAE,OAAO;oBAChB,QAAQ,EAAE,KAAK;iBAChB,CAAC,CAAC;gBACH,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;gBACjC,MAAM;YACR,CAAC;YACD,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE;oBAC1C,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,OAAO,EAAE,MAAM;oBACf,QAAQ,EAAE,KAAK;iBAChB,CAAC,CAAC;gBACH,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;gBACjC,MAAM;YACR,CAAC;YACD,KAAK,GAAG;gBACN,GAAG,IAAI,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBAChD,MAAM;YACR,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE;oBAC1C,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,GAAG,EAAE,MAAM;oBACX,QAAQ,EAAE,KAAK;iBAChB,CAAC,CAAC;gBACH,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;gBACjC,MAAM;YACR,CAAC;YACD,KAAK,GAAG;gBACN,GAAG,IAAI,sBAAsB,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;gBACrD,MAAM;YACR,KAAK,IAAI;gBACP,GAAG,IAAI,sBAAsB,CAC3B,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAC7B,eAAe,CAChB,CAAC;gBACF,MAAM;YACR,KAAK,GAAG,CAAC,CAAC,CAAC;gBACT,MAAM,GAAG,GAAG,IAAI,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;gBAC7C,GAAG,IAAI,sBAAsB,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;gBACpD,MAAM;YACR,CAAC;YACD,KAAK,IAAI,CAAC,CAAC,CAAC;gBACV,MAAM,GAAG,GAAG,IAAI,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;gBAC7C,GAAG,IAAI,sBAAsB,CAC3B,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAC5B,eAAe,CAChB,CAAC;gBACF,MAAM;YACR,CAAC;YACD,KAAK,GAAG;gBACN,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;gBAC/B,MAAM;YACR,KAAK,GAAG;gBACN,GAAG,IAAI,sBAAsB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;gBACvD,MAAM;YACR,KAAK,IAAI;gBACP,GAAG,IAAI,sBAAsB,CAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAC/B,eAAe,CAChB,CAAC;gBACF,MAAM;YACR,KAAK,GAAG;gBACN,GAAG,IAAI,sBAAsB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;gBACvD,MAAM;YACR,KAAK,IAAI;gBACP,GAAG,IAAI,sBAAsB,CAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAC/B,eAAe,CAChB,CAAC;gBACF,MAAM;YACR,KAAK,GAAG,CAAC,CAAC,CAAC;gBACT,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC;gBAC5C,GAAG,IAAI,sBAAsB,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;gBACtD,MAAM;YACR,CAAC;YACD,KAAK,KAAK;gBACR,GAAG,IAAI,sBAAsB,CAC3B,MAAM,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EACpC,eAAe,CAChB,CAAC;gBACF,MAAM;YACR,KAAK,KAAK;gBACR,GAAG,IAAI,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC;gBACtD,MAAM;YACR,KAAK,GAAG,CAAC,CAAC,CAAC;gBACT,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;gBAC7C,GAAG,IAAI,sBAAsB,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;gBACrD,MAAM;YACR,CAAC;YACD,KAAK,KAAK,CAAC,CAAC,CAAC;gBACX,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;gBAC7C,GAAG,IAAI,IAAI,sBAAsB,CAAC,IAAI,EAAE,eAAe,CAAC,EAAE,CAAC;gBAC3D,MAAM;YACR,CAAC;YACD,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC3C,MAAM,MAAM,GAAG;oBACb,aAAa;oBACb,aAAa;oBACb,aAAa;oBACb,aAAa;iBACd,CAAC;gBACF,GAAG,IAAI,MAAM,CAAC,MAAM,CAAE,CAAC;gBACvB,MAAM;YACR,CAAC;YACD,KAAK,GAAG,CAAC,CAAC,CAAC;gBACT,MAAM,GAAG,GAAG,2BAA2B,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC;gBAC1D,GAAG,IAAI,sBAAsB,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;gBACpD,MAAM;YACR,CAAC;YACD,KAAK,KAAK,CAAC,CAAC,CAAC;gBACX,MAAM,GAAG,GAAG,2BAA2B,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC;gBAC1D,GAAG,IAAI,sBAAsB,CAC3B,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAC5B,eAAe,CAChB,CAAC;gBACF,MAAM;YACR,CAAC;YACD,KAAK,GAAG,CAAC,CAAC,CAAC;gBACT,MAAM,EAAE,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC;gBACxD,GAAG,IAAI,sBAAsB,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;gBACnD,MAAM;YACR,CAAC;YACD,KAAK,IAAI,CAAC,CAAC,CAAC;gBACV,MAAM,EAAE,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC;gBACxD,GAAG,IAAI,sBAAsB,CAC3B,MAAM,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAC3B,eAAe,CAChB,CAAC;gBACF,MAAM;YACR,CAAC;YACD,KAAK,GAAG,CAAC,CAAC,CAAC;gBACT,MAAM,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;gBACpC,GAAG,IAAI,sBAAsB,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;gBACpD,MAAM;YACR,CAAC;YACD,KAAK,IAAI,CAAC,CAAC,CAAC;gBACV,MAAM,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;gBACpC,GAAG,IAAI,sBAAsB,CAC3B,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAC5B,eAAe,CAChB,CAAC;gBACF,MAAM;YACR,CAAC;YACD;gBACE,MAAM,IAAI,aAAa,CACrB,8BAA8B,EAC9B,6BAA6B,CAAC,CAAC,MAAM,EAAE,CACxC,CAAC;QACN,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,KAAsC,EACtC,OAAe,EACf,OAAwC;IAExC,OAAO,6BAA6B,CAClC,uBAAuB,EACvB,KAAK,EACL,OAAO,EACP,OAAO,CACR,CAAC;AACJ,CAAC","sourcesContent":["import { scanPattern } from \"./pattern-scanner.js\";\nimport { formatNumberWithSystem } from \"../locale/numbering-system.js\";\nimport { resolveDateFormattingInput } from \"./resolve-date-input.js\";\nimport { defaultCalendarRegistry } from \"../calendar/registry.js\";\nimport { validateAndResolveLocale } from \"../locale/resolve-locale.js\";\nimport { absoluteDayFromGregorianFields } from \"../core/absolute-day.js\";\nimport { getDayOfYearFromAbsoluteDay } from \"../core/day-of-year.js\";\nimport {\n getIsoDayOfWeek,\n getIsoWeekFromAbsoluteDay,\n} from \"../core/iso-week.js\";\nimport { ChroneraError } from \"../errors/errors.js\";\n\nimport type { CalendarRegistry } from \"../calendar/registry.js\";\nimport type {\n CalendarDate,\n FormatDateInput,\n LocalDateTime,\n PatternFormatOptions,\n} from \"../public-types.js\";\n\nexport function formatWithPatternWithRegistry(\n registry: CalendarRegistry,\n input: FormatDateInput | LocalDateTime,\n pattern: string,\n options: Readonly<PatternFormatOptions> = {},\n): string {\n const tokens = scanPattern(pattern);\n const localeInfo = validateAndResolveLocale(options.locale);\n const locale = localeInfo.baseLocale;\n const numberingSystem = options.numberingSystem ?? \"latn\";\n\n // Check if input is LocalDateTime\n let isLocalDateTime = false;\n let localDt: LocalDateTime | undefined;\n if (\"kind\" in input && input.kind === \"local-date-time\") {\n isLocalDateTime = true;\n localDt = input;\n }\n\n let calDate: CalendarDate;\n let absDay: number;\n let hour = 0;\n let minute = 0;\n let second = 0;\n let millisecond = 0;\n let offsetString = \"Z\";\n\n if (isLocalDateTime && localDt) {\n calDate = {\n kind: \"calendar-date\",\n calendar: \"gregory\",\n year: localDt.date.year,\n monthCode: `M${String(localDt.date.month).padStart(2, \"0\")}`,\n month: localDt.date.month,\n day: localDt.date.day,\n era: \"CE\",\n eraYear: localDt.date.year,\n };\n absDay = absoluteDayFromGregorianFields(\n localDt.date.year,\n localDt.date.month,\n localDt.date.day,\n );\n hour = localDt.time.hour;\n minute = localDt.time.minute;\n second = localDt.time.second;\n millisecond = localDt.time.millisecond;\n } else {\n const resolved = resolveDateFormattingInput(\n registry,\n input as FormatDateInput,\n options,\n );\n calDate = resolved.calendarDate;\n absDay = resolved.absoluteDay;\n\n if (resolved.instant) {\n const date = new Date(resolved.instant.epochMilliseconds);\n const tz = resolved.timeZone ?? \"UTC\";\n\n // Project fields using Intl\n const dtf = new Intl.DateTimeFormat(\"en-US\", {\n timeZone: tz,\n hourCycle: \"h23\",\n hour: \"numeric\",\n minute: \"numeric\",\n second: \"numeric\",\n timeZoneName: \"longOffset\",\n });\n\n const parts = dtf.formatToParts(date);\n for (const p of parts) {\n if (p.type === \"hour\") hour = Number.parseInt(p.value, 10);\n if (p.type === \"minute\") minute = Number.parseInt(p.value, 10);\n if (p.type === \"second\") second = Number.parseInt(p.value, 10);\n if (p.type === \"timeZoneName\") {\n // e.g. \"GMT+07:00\" -> \"+07:00\"\n const m = p.value.match(/GMT([+-]\\d{2}:\\d{2})/);\n if (m && m[1]) {\n offsetString = m[1];\n } else if (p.value === \"GMT\") {\n offsetString = \"Z\";\n }\n }\n }\n millisecond = ((resolved.instant.epochMilliseconds % 1000) + 1000) % 1000;\n }\n }\n\n const month =\n calDate.month ?? Number.parseInt(calDate.monthCode.slice(1), 10);\n const year = calDate.eraYear ?? calDate.year;\n\n // Helper for localized text\n const localizedDate = new Date(\n Date.UTC(calDate.year, month - 1, calDate.day),\n );\n\n let out = \"\";\n for (const t of tokens) {\n if (t.type === \"literal\") {\n out += t.value;\n continue;\n }\n\n switch (t.symbol) {\n case \"y\":\n out += formatNumberWithSystem(year, numberingSystem);\n break;\n case \"yy\":\n out += formatNumberWithSystem(\n String(year % 100).padStart(2, \"0\"),\n numberingSystem,\n );\n break;\n case \"yyyy\":\n out += formatNumberWithSystem(\n String(year).padStart(4, \"0\"),\n numberingSystem,\n );\n break;\n case \"M\":\n out += formatNumberWithSystem(month, numberingSystem);\n break;\n case \"MM\":\n out += formatNumberWithSystem(\n String(month).padStart(2, \"0\"),\n numberingSystem,\n );\n break;\n case \"MMM\": {\n const dtf = new Intl.DateTimeFormat(locale, {\n calendar: calDate.calendar,\n month: \"short\",\n timeZone: \"UTC\",\n });\n out += dtf.format(localizedDate);\n break;\n }\n case \"MMMM\": {\n const dtf = new Intl.DateTimeFormat(locale, {\n calendar: calDate.calendar,\n month: \"long\",\n timeZone: \"UTC\",\n });\n out += dtf.format(localizedDate);\n break;\n }\n case \"d\":\n out += formatNumberWithSystem(calDate.day, numberingSystem);\n break;\n case \"dd\":\n out += formatNumberWithSystem(\n String(calDate.day).padStart(2, \"0\"),\n numberingSystem,\n );\n break;\n case \"E\": {\n const dtf = new Intl.DateTimeFormat(locale, {\n calendar: calDate.calendar,\n weekday: \"short\",\n timeZone: \"UTC\",\n });\n out += dtf.format(localizedDate);\n break;\n }\n case \"EEEE\": {\n const dtf = new Intl.DateTimeFormat(locale, {\n calendar: calDate.calendar,\n weekday: \"long\",\n timeZone: \"UTC\",\n });\n out += dtf.format(localizedDate);\n break;\n }\n case \"G\":\n out += calDate.era ?? (year >= 0 ? \"AD\" : \"BC\");\n break;\n case \"GGGG\": {\n const dtf = new Intl.DateTimeFormat(locale, {\n calendar: calDate.calendar,\n era: \"long\",\n timeZone: \"UTC\",\n });\n out += dtf.format(localizedDate);\n break;\n }\n case \"H\":\n out += formatNumberWithSystem(hour, numberingSystem);\n break;\n case \"HH\":\n out += formatNumberWithSystem(\n String(hour).padStart(2, \"0\"),\n numberingSystem,\n );\n break;\n case \"h\": {\n const h12 = hour % 12 === 0 ? 12 : hour % 12;\n out += formatNumberWithSystem(h12, numberingSystem);\n break;\n }\n case \"hh\": {\n const h12 = hour % 12 === 0 ? 12 : hour % 12;\n out += formatNumberWithSystem(\n String(h12).padStart(2, \"0\"),\n numberingSystem,\n );\n break;\n }\n case \"a\":\n out += hour < 12 ? \"AM\" : \"PM\";\n break;\n case \"m\":\n out += formatNumberWithSystem(minute, numberingSystem);\n break;\n case \"mm\":\n out += formatNumberWithSystem(\n String(minute).padStart(2, \"0\"),\n numberingSystem,\n );\n break;\n case \"s\":\n out += formatNumberWithSystem(second, numberingSystem);\n break;\n case \"ss\":\n out += formatNumberWithSystem(\n String(second).padStart(2, \"0\"),\n numberingSystem,\n );\n break;\n case \"S\": {\n const frac1 = Math.floor(millisecond / 100);\n out += formatNumberWithSystem(frac1, numberingSystem);\n break;\n }\n case \"SSS\":\n out += formatNumberWithSystem(\n String(millisecond).padStart(3, \"0\"),\n numberingSystem,\n );\n break;\n case \"XXX\":\n out += offsetString === \"+00:00\" ? \"Z\" : offsetString;\n break;\n case \"Q\": {\n const qNum = Math.floor((month - 1) / 3) + 1;\n out += formatNumberWithSystem(qNum, numberingSystem);\n break;\n }\n case \"QQQ\": {\n const qNum = Math.floor((month - 1) / 3) + 1;\n out += `Q${formatNumberWithSystem(qNum, numberingSystem)}`;\n break;\n }\n case \"QQQQ\": {\n const qIndex = Math.floor((month - 1) / 3);\n const qNames = [\n \"1st quarter\",\n \"2nd quarter\",\n \"3rd quarter\",\n \"4th quarter\",\n ];\n out += qNames[qIndex]!;\n break;\n }\n case \"D\": {\n const doy = getDayOfYearFromAbsoluteDay(absDay).dayOfYear;\n out += formatNumberWithSystem(doy, numberingSystem);\n break;\n }\n case \"DDD\": {\n const doy = getDayOfYearFromAbsoluteDay(absDay).dayOfYear;\n out += formatNumberWithSystem(\n String(doy).padStart(3, \"0\"),\n numberingSystem,\n );\n break;\n }\n case \"w\": {\n const wn = getIsoWeekFromAbsoluteDay(absDay).weekNumber;\n out += formatNumberWithSystem(wn, numberingSystem);\n break;\n }\n case \"ww\": {\n const wn = getIsoWeekFromAbsoluteDay(absDay).weekNumber;\n out += formatNumberWithSystem(\n String(wn).padStart(2, \"0\"),\n numberingSystem,\n );\n break;\n }\n case \"e\": {\n const dow = getIsoDayOfWeek(absDay);\n out += formatNumberWithSystem(dow, numberingSystem);\n break;\n }\n case \"ee\": {\n const dow = getIsoDayOfWeek(absDay);\n out += formatNumberWithSystem(\n String(dow).padStart(2, \"0\"),\n numberingSystem,\n );\n break;\n }\n default:\n throw new ChroneraError(\n \"CHRONERA_PATTERN_TOO_COMPLEX\",\n `Unhandled pattern symbol: ${t.symbol}`,\n );\n }\n }\n\n return out;\n}\n\nexport function formatWithPattern(\n input: FormatDateInput | LocalDateTime,\n pattern: string,\n options?: Readonly<PatternFormatOptions>,\n): string {\n return formatWithPatternWithRegistry(\n defaultCalendarRegistry,\n input,\n pattern,\n options,\n );\n}\n"]}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { ChroneraError } from "../errors/errors.js";
|
|
2
|
+
import { validateAndResolveLocale } from "../locale/resolve-locale.js";
|
|
3
|
+
import { absoluteDayFromGregorianFields } from "../core/absolute-day.js";
|
|
4
|
+
export function formatRelative(target, options) {
|
|
5
|
+
if (!options || !options.relativeTo) {
|
|
6
|
+
throw new ChroneraError("CHRONERA_INCOMPATIBLE_OPTION", "formatRelative requires an explicit 'relativeTo' reference.");
|
|
7
|
+
}
|
|
8
|
+
const { relativeTo } = options;
|
|
9
|
+
const localeInfo = validateAndResolveLocale(options.locale);
|
|
10
|
+
const locale = localeInfo.baseLocale;
|
|
11
|
+
const numeric = options.numeric ?? "auto";
|
|
12
|
+
let diffMs;
|
|
13
|
+
let diffDays;
|
|
14
|
+
if (target.kind === "local-date") {
|
|
15
|
+
if (relativeTo.kind !== "local-date") {
|
|
16
|
+
throw new ChroneraError("CHRONERA_INVALID_DATE", "Target and relativeTo must both be LocalDate or both be Instant.");
|
|
17
|
+
}
|
|
18
|
+
const targetAbs = absoluteDayFromGregorianFields(target.year, target.month, target.day);
|
|
19
|
+
const relAbs = absoluteDayFromGregorianFields(relativeTo.year, relativeTo.month, relativeTo.day);
|
|
20
|
+
diffDays = targetAbs - relAbs;
|
|
21
|
+
diffMs = diffDays * 86400000;
|
|
22
|
+
}
|
|
23
|
+
else if (target.kind === "instant") {
|
|
24
|
+
if (relativeTo.kind !== "instant") {
|
|
25
|
+
throw new ChroneraError("CHRONERA_INVALID_DATE", "Target and relativeTo must both be LocalDate or both be Instant.");
|
|
26
|
+
}
|
|
27
|
+
diffMs = target.epochMilliseconds - relativeTo.epochMilliseconds;
|
|
28
|
+
diffDays = Math.trunc(diffMs / 86400000);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
throw new ChroneraError("CHRONERA_INVALID_DATE", "Expected Instant or LocalDate.");
|
|
32
|
+
}
|
|
33
|
+
let selectedUnit;
|
|
34
|
+
let value;
|
|
35
|
+
if (options.unit !== undefined) {
|
|
36
|
+
selectedUnit = options.unit;
|
|
37
|
+
switch (selectedUnit) {
|
|
38
|
+
case "second":
|
|
39
|
+
value = Math.trunc(diffMs / 1000);
|
|
40
|
+
break;
|
|
41
|
+
case "minute":
|
|
42
|
+
value = Math.trunc(diffMs / 60000);
|
|
43
|
+
break;
|
|
44
|
+
case "hour":
|
|
45
|
+
value = Math.trunc(diffMs / 3600000);
|
|
46
|
+
break;
|
|
47
|
+
case "day":
|
|
48
|
+
value = diffDays;
|
|
49
|
+
break;
|
|
50
|
+
case "week":
|
|
51
|
+
value = Math.trunc(diffDays / 7);
|
|
52
|
+
break;
|
|
53
|
+
case "month":
|
|
54
|
+
value = Math.trunc(diffDays / 30);
|
|
55
|
+
break;
|
|
56
|
+
case "year":
|
|
57
|
+
value = Math.trunc(diffDays / 365);
|
|
58
|
+
break;
|
|
59
|
+
default:
|
|
60
|
+
throw new ChroneraError("CHRONERA_INCOMPATIBLE_OPTION", `Unsupported unit: "${String(selectedUnit)}".`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
const absMs = Math.abs(diffMs);
|
|
65
|
+
const absDays = Math.abs(diffDays);
|
|
66
|
+
if (absMs < 60000) {
|
|
67
|
+
selectedUnit = "second";
|
|
68
|
+
value = Math.trunc(diffMs / 1000);
|
|
69
|
+
}
|
|
70
|
+
else if (absMs < 3600000) {
|
|
71
|
+
selectedUnit = "minute";
|
|
72
|
+
value = Math.trunc(diffMs / 60000);
|
|
73
|
+
}
|
|
74
|
+
else if (absMs < 86400000) {
|
|
75
|
+
selectedUnit = "hour";
|
|
76
|
+
value = Math.trunc(diffMs / 3600000);
|
|
77
|
+
}
|
|
78
|
+
else if (absDays < 7) {
|
|
79
|
+
selectedUnit = "day";
|
|
80
|
+
value = diffDays;
|
|
81
|
+
}
|
|
82
|
+
else if (absDays < 28) {
|
|
83
|
+
selectedUnit = "week";
|
|
84
|
+
value = Math.trunc(diffDays / 7);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
throw new ChroneraError("CHRONERA_INCOMPATIBLE_OPTION", "Difference exceeds 28 calendar days; caller must provide explicit 'month' or 'year' unit in v1.");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const rtf = new Intl.RelativeTimeFormat(locale, { numeric });
|
|
91
|
+
return rtf.format(value, selectedUnit);
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=format-relative.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-relative.js","sourceRoot":"","sources":["../../src/format/format-relative.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChroneraError } from \"../errors/errors.js\";\nimport { validateAndResolveLocale } from \"../locale/resolve-locale.js\";\nimport { absoluteDayFromGregorianFields } from \"../core/absolute-day.js\";\n\nimport type {\n FormatRelativeOptions,\n Instant,\n LocalDate,\n} from \"../public-types.js\";\n\nexport function formatRelative(\n target: Instant | LocalDate,\n options: Readonly<FormatRelativeOptions>,\n): string {\n if (!options || !options.relativeTo) {\n throw new ChroneraError(\n \"CHRONERA_INCOMPATIBLE_OPTION\",\n \"formatRelative requires an explicit 'relativeTo' reference.\",\n );\n }\n\n const { relativeTo } = options;\n const localeInfo = validateAndResolveLocale(options.locale);\n const locale = localeInfo.baseLocale;\n const numeric = options.numeric ?? \"auto\";\n\n let diffMs: number;\n let diffDays: number;\n\n if (target.kind === \"local-date\") {\n if (relativeTo.kind !== \"local-date\") {\n throw new ChroneraError(\n \"CHRONERA_INVALID_DATE\",\n \"Target and relativeTo must both be LocalDate or both be Instant.\",\n );\n }\n const targetAbs = absoluteDayFromGregorianFields(\n target.year,\n target.month,\n target.day,\n );\n const relAbs = absoluteDayFromGregorianFields(\n relativeTo.year,\n relativeTo.month,\n relativeTo.day,\n );\n diffDays = targetAbs - relAbs;\n diffMs = diffDays * 86400000;\n } else if (target.kind === \"instant\") {\n if (relativeTo.kind !== \"instant\") {\n throw new ChroneraError(\n \"CHRONERA_INVALID_DATE\",\n \"Target and relativeTo must both be LocalDate or both be Instant.\",\n );\n }\n diffMs = target.epochMilliseconds - relativeTo.epochMilliseconds;\n diffDays = Math.trunc(diffMs / 86400000);\n } else {\n throw new ChroneraError(\n \"CHRONERA_INVALID_DATE\",\n \"Expected Instant or LocalDate.\",\n );\n }\n\n let selectedUnit: Intl.RelativeTimeFormatUnit;\n let value: number;\n\n if (options.unit !== undefined) {\n selectedUnit = options.unit;\n switch (selectedUnit) {\n case \"second\":\n value = Math.trunc(diffMs / 1000);\n break;\n case \"minute\":\n value = Math.trunc(diffMs / 60000);\n break;\n case \"hour\":\n value = Math.trunc(diffMs / 3600000);\n break;\n case \"day\":\n value = diffDays;\n break;\n case \"week\":\n value = Math.trunc(diffDays / 7);\n break;\n case \"month\":\n value = Math.trunc(diffDays / 30);\n break;\n case \"year\":\n value = Math.trunc(diffDays / 365);\n break;\n default:\n throw new ChroneraError(\n \"CHRONERA_INCOMPATIBLE_OPTION\",\n `Unsupported unit: \"${String(selectedUnit)}\".`,\n );\n }\n } else {\n const absMs = Math.abs(diffMs);\n const absDays = Math.abs(diffDays);\n\n if (absMs < 60000) {\n selectedUnit = \"second\";\n value = Math.trunc(diffMs / 1000);\n } else if (absMs < 3600000) {\n selectedUnit = \"minute\";\n value = Math.trunc(diffMs / 60000);\n } else if (absMs < 86400000) {\n selectedUnit = \"hour\";\n value = Math.trunc(diffMs / 3600000);\n } else if (absDays < 7) {\n selectedUnit = \"day\";\n value = diffDays;\n } else if (absDays < 28) {\n selectedUnit = \"week\";\n value = Math.trunc(diffDays / 7);\n } else {\n throw new ChroneraError(\n \"CHRONERA_INCOMPATIBLE_OPTION\",\n \"Difference exceeds 28 calendar days; caller must provide explicit 'month' or 'year' unit in v1.\",\n );\n }\n }\n\n const rtf = new Intl.RelativeTimeFormat(locale, { numeric });\n return rtf.format(value, selectedUnit);\n}\n"]}
|