Skip to content

April 2026 rebase, part 3#361

Open
ptomato wants to merge 20 commits intomainfrom
rebase-part3
Open

April 2026 rebase, part 3#361
ptomato wants to merge 20 commits intomainfrom
rebase-part3

Conversation

@ptomato
Copy link
Copy Markdown
Contributor

@ptomato ptomato commented Apr 22, 2026

This batch of commits mainly deals with working around weirdnesses in newer ICU versions, and bugfixes to pass the test262 tests dealing with calendar calculations.

There is one normative change, from the November 2025 TC39 plenary. It deals with rounding durations in edge cases and is unlikely to break any working code.

Closes: #360

ptomato and others added 20 commits April 22, 2026 10:32
These don't have defaults, so undefined isn't the same as passing 'auto'

UPSTREAM_COMMIT=ba168d7ab6f91a9015c97708ed8741ea323d3232
This is defined in the Intl Era Monthcode proposal.

See tc39/ecma402#534 and
tc39/proposal-intl-era-monthcode#30

UPSTREAM_COMMIT=25c6205a572a188fbbd02d6bff9e9be2da743ad0
If 'era' is used as a standalone option, it should still trigger
default formatting for PlainTime and PlainMonthDay.

See tc39/proposal-temporal#3049 for more details.

UPSTREAM_COMMIT=0ecf1572df1083e319e01eda5e89b5bec3f83ae6
This was causing the overflow: "reject" to be ignored in leap month
coercion.

UPSTREAM_COMMIT=6f947a70a5332b223860c6082fa04eb6305653f5
These error messages refer to "Chinese year" because they are in the
helperChinese object, but since helperDangi inherits from that it
results in odd error messages. Use ${this.id} instead.

UPSTREAM_COMMIT=af87126b42856ee814ae2e0f99d143586219e7da
Latest versions of Node have this "Mo" prefix in their ICU data, which
completely broke the Chinese and Dangi calendars.

UPSTREAM_COMMIT=835c195b65cba8a836e8806c1243bc819bbc9c79
The check for the Indian calendar BCE bug included the literal string
"Saka", which has been changed to "Śaka" in the latest ICU data. Ignore
the formatted era name and just check the formatted date to see if the
host is vulnerable to the bug.

UPSTREAM_COMMIT=314b112888f679156142ac15135131959ec32ff2
CLDR has removed the "ERA0" code from the Coptic calendar but it looks
like they neglected to actually remove the era - if you try to format a
date with a negative era year, it prints a positive era year and omits
the era code (the final part of formatToParts() is a literal " " part,
which normally should be followed by an era part.) Handle this
eventuality with a special case.

UPSTREAM_COMMIT=49e2d1d385a05c4402d954b517105cfd609ac362
We need to do the non-negative modulo here, otherwise all negative years
are leap years.

UPSTREAM_COMMIT=0df570c70ef9d6b97f4bdd204ac753ad7fa3cd93
…ring durations

See tc39/proposal-temporal#3168

UPSTREAM_COMMIT=17e12be0af42a02b3389d22417923f29f93c16c5
The spec mandates that the shape of the fields property bag must be
checked (and a TypeError thrown if incorrect) before any RangeError
conditions are checked.

See #3166

UPSTREAM_COMMIT=98991268f1f06a1865f136c196383076a50fdcde
As per tc39/proposal-temporal#2940 this belongs
in NonISOResolveFields, before any RangeError conditions are checked.

UPSTREAM_COMMIT=99e43310d04cff672ccd38cd8470596f984287eb
I have gotten confused by the lack of resolveLunisolarMonth here several
times, so add a comment explaining that it's intentional.

UPSTREAM_COMMIT=66268cb2cc2297228e416179b0d922a86e0e18ed
UPSTREAM_COMMIT=264900c8312711c000db1b70e574284e2fd319a4
This fixes a bug where adding 1 year 0 months would skip applying the
overflow option. Brings the polyfill calendar code in line with the
spec text of proposal-intl-era-monthcode.

(For example, in 2020-02-29[u-ca=gregory] + P1Y with overflow: "reject")

UPSTREAM_COMMIT=8a51e7e8cd849d83db912c42523eb1802cb3799e
UPSTREAM_COMMIT=419764273a68b77edd6254a975666c7d9413a7de
In the tabular Hijri calendars, the months have a set number of days
with only one month varying between 29 and 30 days in leap years. In
the observational Hijri calendar (islamic-umalqura) any month can have
30 days.

This applies that information to make maxLengthOfMonthCodeInAnyYear() in
helperIslamic more accurate. It prevents a slow search roundtripping
through 20 years when code like this is executed:

    Temporal.PlainMonthDay.from({
      calendar: 'islamic-tbla',
      monthCode: 'M10',
      day: 30
    })

This PlainMonthDay shouldn't exist. The change makes it fail immediately
rather than exhausting the search space.

This is just a polyfill optimization. The spec text remains correct.

UPSTREAM_COMMIT=b7d96ecbc24fe1f284b9454550ac76b1df677ae2
In hindsight, when I wrote the maxLengthOfMonthCodeInAnyYear() code in
e977eff0 I put it in a slightly odd place. There is no need to check
overflow in each iteration of the search loop, we can check it at the
beginning.

And in fact this code was buggy: PlainMonthDays created from
out-of-range days with overflow: 'constrain' would sometimes get wrong
reference years. For example:

   Temporal.PlainMonthDay.from({
     calendar: 'gregory',
     monthCode: 'M12',
     day: 32
   })

This would get the incorrect reference year 1971, and would actually
produce a different PlainMonthDay instance from the same call with day:
31, which would get the correct reference year 1972.

This was a polyfill-only bug. No change needed to the spec text.

UPSTREAM_COMMIT=ef85a85f791085b4b0b58083a4e9e6890638a74b
We need to add some new tests to the expected failures file: they expose
a bug in ICU4C where the wrong leap month was calculated for the Chinese
calendar in 1987.

UPSTREAM_COMMIT=2cee76afbb27bda99126d0b7e69fc606499c0b2b
@ptomato ptomato requested review from 12wrigja and justingrant April 22, 2026 17:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Malformed leap month suffix while implementing Chinese calendar

2 participants