Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 99473681ff5ee5bc7d666904274b1491a81c5196
https://github.com/WebKit/WebKit/commit/99473681ff5ee5bc7d666904274b1491a81c5196
Author: Yijia Huang <[email protected]>
Date: 2026-08-02 (Sun, 02 Aug 2026)
Changed paths:
M JSTests/stress/intl-datetimeformat.js
M JSTests/stress/temporal-calendar-canonical-set.js
M JSTests/stress/temporal-calendar-icu-bridge-non-iso.js
A JSTests/stress/temporal-era-aliases.js
A JSTests/stress/temporal-era-boundaries.js
A JSTests/stress/temporal-extreme-proleptic.js
A JSTests/stress/temporal-hebrew-year0-kislev.js
A JSTests/stress/temporal-lunisolar-and-wrappers.js
A JSTests/stress/temporal-nonISO-arithmetic.js
A JSTests/stress/temporal-nonISO-with.js
A JSTests/stress/temporal-nonisoresolvefields-monthcode-validation.js
A JSTests/stress/temporal-resolvefields-error-ordering.js
M JSTests/test262/config.yaml
M Source/JavaScriptCore/API/tests/TemporalCoreTest.cpp
M Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp
M Source/JavaScriptCore/runtime/IntlObject.cpp
M Source/JavaScriptCore/runtime/IntlObject.h
M Source/JavaScriptCore/runtime/TemporalCalendar.cpp
M Source/JavaScriptCore/runtime/TemporalPlainDatePrototype.cpp
M Source/JavaScriptCore/runtime/TemporalPlainDateTimePrototype.cpp
M Source/JavaScriptCore/runtime/TemporalPlainMonthDayPrototype.cpp
M Source/JavaScriptCore/runtime/TemporalZonedDateTimePrototype.cpp
M Source/JavaScriptCore/runtime/temporal/core/CalendarFields.cpp
M Source/JavaScriptCore/runtime/temporal/core/CalendarFields.h
M Source/JavaScriptCore/runtime/temporal/core/CalendarICUBridge.cpp
M Source/JavaScriptCore/runtime/temporal/core/CalendarICUBridge.h
M Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml
Log Message:
-----------
[JSC][Temporal][Intl.Era] Implement intl-era-monthcode
https://bugs.webkit.org/show_bug.cgi?id=319855
rdar://182753821
Reviewed by Yusuke Suzuki.
Implement the Stage 4 proposal-intl-era-monthcode[1] end-to-end and drop the
useIntlEraMonthcode transition flag.
CalendarICUBridge is consolidated around the intl-era spec ops. A canonical
eraTable() replaces per-calendar if-ladders in CanonicalizeEraInCalendar,
CalendarDateArithmeticYearForEraYear, and RemapNonPositiveEraYear.
New IsValidMonthCodeForCalendar, YearContainsMonthCode, ConstrainMonthCode
(with ~constrain~/~reject~ overflow), and MonthCodeOrdinalInYear share
algorithms via cursor-taking Internal variants to avoid withCalendar
cache-lock re-entry.
Era emission is unified via emitEraProleptic and
emitEraFromICU. Calendar-category predicates and ICU boilerplate helpers
replace repeated inline patterns.
Audited 7 distinct calendar-behavior clusters in CalendarICUBridge.cpp and
IntlDateTimeFormat.cpp against standalone ICU repros and icu4x/temporal_rs
cross-checks. 6 of the 7 trace to a confirmed, filable ICU4C calendar-data
bug; the 7th (Hebrew never setting UCAL_IS_LEAP_MONTH) is confirmed
intentional API design, not a bug, and needs no radar. Of the 6 confirmed
bugs, 5 are tagged ICU4C-WORKAROUND in code and are pure stopgaps that fully
disappear once ICU ships a fix; the 6th (Chinese/Dangi, rdar://182965648) is
deliberately left untagged as a workaround, since its ±10000-year ISO
fallback is a permanent design choice independent of that specific bug (see
below).
- rdar://182952830 (stale ucal_getLimit after ucal_add(MONTH, -1)),
rdar://182960658 (Indian/Saka extreme-year round-trip), and
rdar://182963532 (Buddhist/ROC/Japanese pre-1582 Julian arithmetic)
already had correct, complete workarounds; no changes needed. All three
fully disappear once ICU fixes the underlying behavior.
- rdar://182965648 (Chinese/Dangi: ucal_getMillis succeeds but the paired
ucal_get(UCAL_EXTENDED_YEAR) fails at extreme years) was only handled on
the construction side (NonISOCalendarDateToISO). Every calendar field
accessor (year, month, day, monthCode, dayOfYear, daysInMonth, daysInYear,
monthsInYear) is now fixed to fall back to the ISO calendar's own fields
beyond the same ±10000 threshold, instead of throwing (RangeError: Failed
to read calendar fields from ICU) or silently returning stale, incorrect
values. Unlike the other five, this fallback does NOT go away once ICU
fixes the ucal_getMillis/ucal_get inconsistency: the ±10000 threshold
matches icu4x's own WELL_BEHAVED_ASTRONOMICAL_RANGE and is required by
test262 extreme-dates.js regardless of that specific ICU bug, since
Chinese/Dangi astronomical calculations are unreliable that far out on
any implementation.
- rdar://182953351 (Islamic calendar era architecturally locked at 0, no
pre-Hijra era; Coptic never emits its second era for pre-AM dates) is
partially fixed: the era-text override now only fires when the caller
actually requested an era field (it previously spliced era text into
format()/formatToParts() output unconditionally). formatRange() and
formatRangeToParts() still don't apply the override at all; fixing that
properly needs per-endpoint override text (a range whose ends fall on
opposite sides of the era boundary can't be expressed with one override
string), which is complexity not worth adding to a workaround that fully
disappears once ICU selects the correct era natively.
- rdar://182958553 (Hebrew calendar year 0 classified "Deficient" leap year
instead of "Regular", giving Kislev 29 days instead of 30) remains only
partially addressed: the existing workaround relabels ICU's single native
Tevet D1 slot as the fabricated Kislev D30, but never shifts the rest of
the year by the day it inserts, so dayOfYear under-counts by 1 from Tevet
D1 onward and the true Tevet D1 is unreachable. A correct fix means
re-deriving every field for the remainder of year 0, which isn't worth
hand-rolling for a workaround that fully disappears once ICU's
classification matches icu4x.
The last two are left as FIXMEs with regression tests gated behind
`if (false)` (temporal-hebrew-year0-kislev.js, intl-datetimeformat.js),
to be flipped on once ICU ships the underlying fixes, rather than growing
more workaround logic in this codebase. intl-datetimeformat.js also gained
coverage pinning down the era-text override's known compatibility boundary
(hardcoded English text, era width ignored, wrong pattern position for
non-English locales) so it stays visible without expanding the override's
scope.
[1] https://github.com/tc39/proposal-intl-era-monthcode
Tests: JSTests/stress/intl-datetimeformat.js
JSTests/stress/temporal-era-aliases.js
JSTests/stress/temporal-era-boundaries.js
JSTests/stress/temporal-extreme-proleptic.js
JSTests/stress/temporal-hebrew-year0-kislev.js
JSTests/stress/temporal-lunisolar-and-wrappers.js
JSTests/stress/temporal-nonISO-arithmetic.js
JSTests/stress/temporal-nonISO-with.js
JSTests/stress/temporal-nonisoresolvefields-monthcode-validation.js
JSTests/stress/temporal-resolvefields-error-ordering.js
Source/JavaScriptCore/API/tests/TemporalCoreTest.cpp
Canonical link: https://commits.webkit.org/318428@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications