@formatjs/intl-datetimeformat 7.1.2 → 7.2.1

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@formatjs/intl-datetimeformat",
3
3
  "description": "Intl.DateTimeFormat polyfill",
4
- "version": "7.1.2",
4
+ "version": "7.2.1",
5
5
  "license": "MIT",
6
6
  "author": "Long Ho <holevietlong@gmail.com>",
7
7
  "type": "module",
@@ -16,14 +16,14 @@
16
16
  "./locale-data/*": "./locale-data/*"
17
17
  },
18
18
  "dependencies": {
19
- "decimal.js": "^10.4.3",
20
- "tslib": "^2.8.0",
21
- "@formatjs/intl-localematcher": "0.7.5",
22
- "@formatjs/ecma402-abstract": "3.0.8"
19
+ "decimal.js": "^10.6.0",
20
+ "tslib": "^2.8.1",
21
+ "@formatjs/ecma402-abstract": "3.1.1",
22
+ "@formatjs/intl-localematcher": "0.8.1"
23
23
  },
24
24
  "devDependencies": {
25
- "@formatjs/intl-getcanonicallocales": "3.1.2",
26
- "@formatjs/intl-locale": "5.1.2"
25
+ "@formatjs/intl-getcanonicallocales": "3.2.1",
26
+ "@formatjs/intl-locale": "5.2.1"
27
27
  },
28
28
  "bugs": "https://github.com/formatjs/formatjs/issues",
29
29
  "homepage": "https://github.com/formatjs/formatjs#readme",
package/polyfill.iife.js CHANGED
@@ -2536,7 +2536,6 @@
2536
2536
  }
2537
2537
  }
2538
2538
  var createMemoizedNumberFormat = memoize((...args) => new Intl.NumberFormat(...args), { strategy: strategies.variadic });
2539
- var createMemoizedDateTimeFormat = memoize((...args) => new Intl.DateTimeFormat(...args), { strategy: strategies.variadic });
2540
2539
  var createMemoizedPluralRules = memoize((...args) => new Intl.PluralRules(...args), { strategy: strategies.variadic });
2541
2540
  var createMemoizedLocale = memoize((...args) => new Intl.Locale(...args), { strategy: strategies.variadic });
2542
2541
  var createMemoizedListFormat = memoize((...args) => new Intl.ListFormat(...args), { strategy: strategies.variadic });
@@ -2552,7 +2551,10 @@
2552
2551
  if (typeof arg === "number") {
2553
2552
  return new Decimal(arg);
2554
2553
  }
2555
- invariant(typeof arg !== "bigint" && typeof arg !== "symbol", "BigInt and Symbol are not supported", TypeError);
2554
+ if (typeof arg === "bigint") {
2555
+ return new Decimal(arg.toString());
2556
+ }
2557
+ invariant(typeof arg !== "symbol", "Symbol is not supported", TypeError);
2556
2558
  if (arg === void 0) {
2557
2559
  return new Decimal(NaN);
2558
2560
  }
@@ -2963,7 +2965,7 @@
2963
2965
  Decimal.set({ toExpPos: 100 });
2964
2966
 
2965
2967
  // node_modules/.aspect_rules_js/@formatjs+ecma402-abstract@0.0.0/node_modules/@formatjs/ecma402-abstract/regex.generated.js
2966
- var S_UNICODE_REGEX = /[\$\+<->\^`\|~\xA2-\xA6\xA8\xA9\xAC\xAE-\xB1\xB4\xB8\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0384\u0385\u03F6\u0482\u058D-\u058F\u0606-\u0608\u060B\u060E\u060F\u06DE\u06E9\u06FD\u06FE\u07F6\u07FE\u07FF\u09F2\u09F3\u09FA\u09FB\u0AF1\u0B70\u0BF3-\u0BFA\u0C7F\u0D4F\u0D79\u0E3F\u0F01-\u0F03\u0F13\u0F15-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE\u0FCF\u0FD5-\u0FD8\u109E\u109F\u1390-\u1399\u166D\u17DB\u1940\u19DE-\u19FF\u1B61-\u1B6A\u1B74-\u1B7C\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u2044\u2052\u207A-\u207C\u208A-\u208C\u20A0-\u20BF\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F\u218A\u218B\u2190-\u2307\u230C-\u2328\u232B-\u2426\u2440-\u244A\u249C-\u24E9\u2500-\u2767\u2794-\u27C4\u27C7-\u27E5\u27F0-\u2982\u2999-\u29D7\u29DC-\u29FB\u29FE-\u2B73\u2B76-\u2B95\u2B97-\u2BFF\u2CE5-\u2CEA\u2E50\u2E51\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3004\u3012\u3013\u3020\u3036\u3037\u303E\u303F\u309B\u309C\u3190\u3191\u3196-\u319F\u31C0-\u31E3\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA700-\uA716\uA720\uA721\uA789\uA78A\uA828-\uA82B\uA836-\uA839\uAA77-\uAA79\uAB5B\uAB6A\uAB6B\uFB29\uFBB2-\uFBC1\uFDFC\uFDFD\uFE62\uFE64-\uFE66\uFE69\uFF04\uFF0B\uFF1C-\uFF1E\uFF3E\uFF40\uFF5C\uFF5E\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFFC\uFFFD]|\uD800[\uDD37-\uDD3F\uDD79-\uDD89\uDD8C-\uDD8E\uDD90-\uDD9C\uDDA0\uDDD0-\uDDFC]|\uD802[\uDC77\uDC78\uDEC8]|\uD805\uDF3F|\uD807[\uDFD5-\uDFF1]|\uD81A[\uDF3C-\uDF3F\uDF45]|\uD82F\uDC9C|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDE8\uDE00-\uDE41\uDE45\uDF00-\uDF56]|\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85\uDE86]|\uD838[\uDD4F\uDEFF]|\uD83B[\uDCAC\uDCB0\uDD2E\uDEF0\uDEF1]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD0D-\uDDAD\uDDE6-\uDE02\uDE10-\uDE3B\uDE40-\uDE48\uDE50\uDE51\uDE60-\uDE65\uDF00-\uDFFF]|\uD83D[\uDC00-\uDED7\uDEE0-\uDEEC\uDEF0-\uDEFC\uDF00-\uDF73\uDF80-\uDFD8\uDFE0-\uDFEB]|\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDCB0\uDCB1\uDD00-\uDD78\uDD7A-\uDDCB\uDDCD-\uDE53\uDE60-\uDE6D\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6\uDF00-\uDF92\uDF94-\uDFCA]/;
2968
+ var S_UNICODE_REGEX = /[\$\+<->\^`\|~\xA2-\xA6\xA8\xA9\xAC\xAE-\xB1\xB4\xB8\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0384\u0385\u03F6\u0482\u058D-\u058F\u0606-\u0608\u060B\u060E\u060F\u06DE\u06E9\u06FD\u06FE\u07F6\u07FE\u07FF\u0888\u09F2\u09F3\u09FA\u09FB\u0AF1\u0B70\u0BF3-\u0BFA\u0C7F\u0D4F\u0D79\u0E3F\u0F01-\u0F03\u0F13\u0F15-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE\u0FCF\u0FD5-\u0FD8\u109E\u109F\u1390-\u1399\u166D\u17DB\u1940\u19DE-\u19FF\u1B61-\u1B6A\u1B74-\u1B7C\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u2044\u2052\u207A-\u207C\u208A-\u208C\u20A0-\u20C1\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F\u218A\u218B\u2190-\u2307\u230C-\u2328\u232B-\u2429\u2440-\u244A\u249C-\u24E9\u2500-\u2767\u2794-\u27C4\u27C7-\u27E5\u27F0-\u2982\u2999-\u29D7\u29DC-\u29FB\u29FE-\u2B73\u2B76-\u2BFF\u2CE5-\u2CEA\u2E50\u2E51\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFF\u3004\u3012\u3013\u3020\u3036\u3037\u303E\u303F\u309B\u309C\u3190\u3191\u3196-\u319F\u31C0-\u31E5\u31EF\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA700-\uA716\uA720\uA721\uA789\uA78A\uA828-\uA82B\uA836-\uA839\uAA77-\uAA79\uAB5B\uAB6A\uAB6B\uFB29\uFBB2-\uFBD2\uFD40-\uFD4F\uFD90\uFD91\uFDC8-\uFDCF\uFDFC-\uFDFF\uFE62\uFE64-\uFE66\uFE69\uFF04\uFF0B\uFF1C-\uFF1E\uFF3E\uFF40\uFF5C\uFF5E\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFFC\uFFFD]|\uD800[\uDD37-\uDD3F\uDD79-\uDD89\uDD8C-\uDD8E\uDD90-\uDD9C\uDDA0\uDDD0-\uDDFC]|\uD802[\uDC77\uDC78\uDEC8]|\uD803[\uDD8E\uDD8F\uDED1-\uDED8]|\uD805\uDF3F|\uD807[\uDFD5-\uDFF1]|\uD81A[\uDF3C-\uDF3F\uDF45]|\uD82F\uDC9C|\uD833[\uDC00-\uDCEF\uDCFA-\uDCFC\uDD00-\uDEB3\uDEBA-\uDED0\uDEE0-\uDEF0\uDF50-\uDFC3]|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDEA\uDE00-\uDE41\uDE45\uDF00-\uDF56]|\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85\uDE86]|\uD838[\uDD4F\uDEFF]|\uD83B[\uDCAC\uDCB0\uDD2E\uDEF0\uDEF1]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD0D-\uDDAD\uDDE6-\uDE02\uDE10-\uDE3B\uDE40-\uDE48\uDE50\uDE51\uDE60-\uDE65\uDF00-\uDFFF]|\uD83D[\uDC00-\uDED8\uDEDC-\uDEEC\uDEF0-\uDEFC\uDF00-\uDFD9\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDCB0-\uDCBB\uDCC0\uDCC1\uDCD0-\uDCD8\uDD00-\uDE57\uDE60-\uDE6D\uDE70-\uDE7C\uDE80-\uDE8A\uDE8E-\uDEC6\uDEC8\uDECD-\uDEDC\uDEDF-\uDEEA\uDEEF-\uDEF8\uDF00-\uDF92\uDF94-\uDFEF\uDFFA]/;
2967
2969
 
2968
2970
  // node_modules/.aspect_rules_js/@formatjs+ecma402-abstract@0.0.0/node_modules/@formatjs/ecma402-abstract/NumberFormat/format_to_parts.js
2969
2971
  var CARET_S_UNICODE_REGEX = new RegExp(`^${S_UNICODE_REGEX.source}`);
@@ -6814,7 +6816,8 @@
6814
6816
  getInternalSlots: getInternalSlots2,
6815
6817
  localeData,
6816
6818
  getDefaultTimeZone,
6817
- tzData
6819
+ tzData,
6820
+ rangeFormatOptions
6818
6821
  }) {
6819
6822
  x = TimeClip(x);
6820
6823
  const internalSlots = getInternalSlots2(dtf);
@@ -6911,7 +6914,7 @@
6911
6914
  }
6912
6915
  }
6913
6916
  if (p === "hour" && hourCycle === "h24") {
6914
- if (v === 0) {
6917
+ if (v === 0 && !(rangeFormatOptions == null ? void 0 : rangeFormatOptions.isDifferentDate)) {
6915
6918
  v = 24;
6916
6919
  }
6917
6920
  }
@@ -7038,6 +7041,7 @@
7038
7041
  let rangePattern;
7039
7042
  let dateFieldsPracticallyEqual = true;
7040
7043
  let patternContainsLargerDateField = false;
7044
+ let firstDifferingField;
7041
7045
  for (const fieldName of TABLE_2_FIELDS) {
7042
7046
  if (dateFieldsPracticallyEqual && !patternContainsLargerDateField) {
7043
7047
  let rp = fieldName in rangePatterns ? rangePatterns[fieldName] : void 0;
@@ -7050,6 +7054,7 @@
7050
7054
  let v2 = tm2.hour;
7051
7055
  if (v1 > 11 && v2 < 11 || v1 < 11 && v2 > 11) {
7052
7056
  dateFieldsPracticallyEqual = false;
7057
+ firstDifferingField = fieldName;
7053
7058
  }
7054
7059
  } else if (fieldName === "dayPeriod") {
7055
7060
  } else if (fieldName === "fractionalSecondDigits") {
@@ -7065,12 +7070,14 @@
7065
7070
  );
7066
7071
  if (!SameValue(v1, v2)) {
7067
7072
  dateFieldsPracticallyEqual = false;
7073
+ firstDifferingField = fieldName;
7068
7074
  }
7069
7075
  } else {
7070
7076
  let v1 = tm1[fieldName];
7071
7077
  let v2 = tm2[fieldName];
7072
7078
  if (!SameValue(v1, v2)) {
7073
7079
  dateFieldsPracticallyEqual = false;
7080
+ firstDifferingField = fieldName;
7074
7081
  }
7075
7082
  }
7076
7083
  }
@@ -7088,6 +7095,10 @@
7088
7095
  }
7089
7096
  return result2;
7090
7097
  }
7098
+ if (rangePattern === void 0 && firstDifferingField === "ampm") {
7099
+ rangePattern = "hour" in rangePatterns ? rangePatterns["hour"] : void 0;
7100
+ }
7101
+ const datesDiffer = tm1.year !== tm2.year || tm1.month !== tm2.month || tm1.day !== tm2.day;
7091
7102
  let result = [];
7092
7103
  if (rangePattern === void 0) {
7093
7104
  rangePattern = rangePatterns.default;
@@ -7123,7 +7134,9 @@
7123
7134
  z = y;
7124
7135
  }
7125
7136
  const patternParts = PartitionPattern(pattern2);
7126
- let partResult = FormatDateTimePattern(dtf, patternParts, z, implDetails);
7137
+ let partResult = FormatDateTimePattern(dtf, patternParts, z, __spreadProps(__spreadValues({}, implDetails), {
7138
+ rangeFormatOptions: { isDifferentDate: datesDiffer }
7139
+ }));
7127
7140
  for (const r of partResult) {
7128
7141
  r.source = source;
7129
7142
  }
@@ -5,10 +5,13 @@ export interface FormatDateTimePatternImplDetails {
5
5
  getInternalSlots(dtf: Intl.DateTimeFormat | DateTimeFormat): IntlDateTimeFormatInternal;
6
6
  localeData: Record<string, DateTimeFormatLocaleInternalData>;
7
7
  getDefaultTimeZone(): string;
8
+ rangeFormatOptions?: {
9
+ isDifferentDate?: boolean;
10
+ };
8
11
  }
9
12
  /**
10
13
  * https://tc39.es/ecma402/#sec-partitiondatetimepattern
11
14
  * @param dtf
12
15
  * @param x
13
16
  */
14
- export declare function FormatDateTimePattern(dtf: Intl.DateTimeFormat | DateTimeFormat, patternParts: IntlDateTimeFormatPart[], x: Decimal, { getInternalSlots, localeData, getDefaultTimeZone, tzData }: FormatDateTimePatternImplDetails & ToLocalTimeImplDetails): IntlDateTimeFormatPart[];
17
+ export declare function FormatDateTimePattern(dtf: Intl.DateTimeFormat | DateTimeFormat, patternParts: IntlDateTimeFormatPart[], x: Decimal, { getInternalSlots, localeData, getDefaultTimeZone, tzData, rangeFormatOptions }: FormatDateTimePatternImplDetails & ToLocalTimeImplDetails): IntlDateTimeFormatPart[];
@@ -30,7 +30,7 @@ function offsetToGmtString(gmtFormat, hourFormat, offsetInMs, style) {
30
30
  * @param dtf
31
31
  * @param x
32
32
  */
33
- export function FormatDateTimePattern(dtf, patternParts, x, { getInternalSlots, localeData, getDefaultTimeZone, tzData }) {
33
+ export function FormatDateTimePattern(dtf, patternParts, x, { getInternalSlots, localeData, getDefaultTimeZone, tzData, rangeFormatOptions }) {
34
34
  x = TimeClip(x);
35
35
  /** IMPL START */
36
36
  const internalSlots = getInternalSlots(dtf);
@@ -130,8 +130,21 @@ export function FormatDateTimePattern(dtf, patternParts, x, { getInternalSlots,
130
130
  v = 12;
131
131
  }
132
132
  }
133
+ // GH #4535: In h24 format, midnight is typically shown as 24:00 (end of day).
134
+ // However, in date ranges where dates differ (e.g., "May 3, 22:00 – May 4, 00:00"),
135
+ // showing "May 4, 24:00" is semantically incorrect because 24:00 of May 4 would
136
+ // actually be May 5, 00:00. In this case, keep midnight as 00:00 for clarity.
137
+ //
138
+ // LDML Spec (UTS #35): "Tuesday 24:00 = Wednesday 00:00" - they represent the same
139
+ // instant. The 'k' symbol (1-24) means 24:00 represents the END of day, not the start.
140
+ // See: https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
141
+ //
142
+ // Note: ICU4J's SimpleDateFormat always converts 0→24 for 'k' pattern without this
143
+ // range-aware check. Our fix is more semantically correct for date range formatting.
144
+ // See: https://github.com/unicode-org/icu/blob/main/icu4j/main/core/src/main/java/com/ibm/icu/text/SimpleDateFormat.java
133
145
  if (p === "hour" && hourCycle === "h24") {
134
- if (v === 0) {
146
+ if (v === 0 && !rangeFormatOptions?.isDifferentDate) {
147
+ // Only convert 0 to 24 when NOT in a range with different dates
135
148
  v = 24;
136
149
  }
137
150
  }
@@ -46,6 +46,8 @@ export function PartitionDateTimeRangePattern(dtf, x, y, implDetails) {
46
46
  let rangePattern;
47
47
  let dateFieldsPracticallyEqual = true;
48
48
  let patternContainsLargerDateField = false;
49
+ // Track the first field that differs between the two dates
50
+ let firstDifferingField;
49
51
  for (const fieldName of TABLE_2_FIELDS) {
50
52
  if (dateFieldsPracticallyEqual && !patternContainsLargerDateField) {
51
53
  let rp = fieldName in rangePatterns ? rangePatterns[fieldName] : undefined;
@@ -58,6 +60,7 @@ export function PartitionDateTimeRangePattern(dtf, x, y, implDetails) {
58
60
  let v2 = tm2.hour;
59
61
  if (v1 > 11 && v2 < 11 || v1 < 11 && v2 > 11) {
60
62
  dateFieldsPracticallyEqual = false;
63
+ firstDifferingField = fieldName;
61
64
  }
62
65
  } else if (fieldName === "dayPeriod") {} else if (fieldName === "fractionalSecondDigits") {
63
66
  let fractionalSecondDigits = internalSlots.fractionalSecondDigits;
@@ -68,12 +71,14 @@ export function PartitionDateTimeRangePattern(dtf, x, y, implDetails) {
68
71
  let v2 = Math.floor(tm2.millisecond * 10 ** (fractionalSecondDigits - 3));
69
72
  if (!SameValue(v1, v2)) {
70
73
  dateFieldsPracticallyEqual = false;
74
+ firstDifferingField = fieldName;
71
75
  }
72
76
  } else {
73
77
  let v1 = tm1[fieldName];
74
78
  let v2 = tm2[fieldName];
75
79
  if (!SameValue(v1, v2)) {
76
80
  dateFieldsPracticallyEqual = false;
81
+ firstDifferingField = fieldName;
77
82
  }
78
83
  }
79
84
  }
@@ -86,6 +91,25 @@ export function PartitionDateTimeRangePattern(dtf, x, y, implDetails) {
86
91
  }
87
92
  return result;
88
93
  }
94
+ // GH #4535: ICU4J-style AM_PM → HOUR fallback.
95
+ // When AM_PM differs but no AM_PM pattern exists, try the HOUR pattern.
96
+ // This handles cases where CLDR provides 'H' (24-hour) patterns but not 'h' (12-hour),
97
+ // or the skeleton uses hour12:true but CLDR only has 24-hour interval patterns.
98
+ //
99
+ // ICU4J DateIntervalFormat.java genIntervalPattern() method (~line 1825):
100
+ // // for 24 hour system, interval patterns in resource file
101
+ // // might not include pattern when am_pm differ,
102
+ // // which should be the same as hour differ.
103
+ // if (field == Calendar.AM_PM) {
104
+ // pattern = fInfo.getIntervalPattern(bestSkeleton, Calendar.HOUR);
105
+ // }
106
+ // See: https://github.com/unicode-org/icu/blob/main/icu4j/main/core/src/main/java/com/ibm/icu/text/DateIntervalFormat.java#L2018
107
+ // LDML Spec: https://unicode.org/reports/tr35/tr35-dates.html#intervalFormats
108
+ if (rangePattern === undefined && firstDifferingField === "ampm") {
109
+ rangePattern = "hour" in rangePatterns ? rangePatterns["hour"] : undefined;
110
+ }
111
+ // GH #4535: Check if dates (year/month/day) differ for h24 midnight handling
112
+ const datesDiffer = tm1.year !== tm2.year || tm1.month !== tm2.month || tm1.day !== tm2.day;
89
113
  let result = [];
90
114
  if (rangePattern === undefined) {
91
115
  rangePattern = rangePatterns.default;
@@ -161,7 +185,10 @@ export function PartitionDateTimeRangePattern(dtf, x, y, implDetails) {
161
185
  z = y;
162
186
  }
163
187
  const patternParts = PartitionPattern(pattern);
164
- let partResult = FormatDateTimePattern(dtf, patternParts, z, implDetails);
188
+ let partResult = FormatDateTimePattern(dtf, patternParts, z, {
189
+ ...implDetails,
190
+ rangeFormatOptions: { isDifferentDate: datesDiffer }
191
+ });
165
192
  for (const r of partResult) {
166
193
  r.source = source;
167
194
  }
@@ -1,5 +1,3 @@
1
- // @generated
2
- // prettier-ignore
3
1
  declare const data: {
4
2
  abbrvs: string;
5
3
  offsets: string;
@@ -1,5 +1,3 @@
1
- // @generated
2
- // prettier-ignore
3
1
  declare const _default: {
4
2
  "Africa/Accra": string;
5
3
  "Africa/Addis_Ababa": string;
@@ -1,4 +1,2 @@
1
- // Type-only circular import
2
- // eslint-disable-next-line import/no-cycle
3
1
  import { type DateTimeFormat, type IntlDateTimeFormatInternal } from "@formatjs/ecma402-abstract";
4
2
  export default function getInternalSlots(x: DateTimeFormat): IntlDateTimeFormatInternal;
package/src/packer.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type UnpackedData, type PackedData } from "./types.js";
1
+ import { type UnpackedData, type PackedData } from "./types.ts";
2
2
  import { type UnpackedZoneData } from "@formatjs/ecma402-abstract";
3
3
  export declare function pack(data: UnpackedData): PackedData;
4
4
  export declare function unpack(data: PackedData): Record<string, UnpackedZoneData[]>;
package/test262-main.d.ts CHANGED
@@ -1,4 +1,2 @@
1
- /* @generated */
2
- // @ts-nocheck
3
1
  import "./polyfill-force.js";
4
2
  export {};