Commit graph

12 commits

Author SHA1 Message Date
Timothy Flynn
34d7a8fa69 LibUnicode: Handle ICU vs ECMA-402 era formatting discrepancies
ICU's Islamic calendar implementations always set ERA=0, even for dates
before the Hijra (622 CE), using negative year values instead. However,
the CLDR defines two eras: "Anno Hegirae" (era 0) and "Before Hijrah"
(era 1). ECMA-402 expects distinct era names in formatToParts output.
Similarly, ICU's Coptic calendar has an empty CLDR era 0 name, causing
the era parts to be omitted entirely from formatted output.

This patch adds another icu::Calendar subclass to handle these cases.
2026-03-13 14:43:45 -04:00
Timothy Flynn
3c0d0d248c LibUnicode: Move icu::Calendar subclass to a Calendars folder
There will be another calendar subclass coming up, so let's give them a
bit of organization.
2026-03-13 14:43:45 -04:00
Timothy Flynn
ef899027c5 LibUnicode: Use a calendar with icu4x glue to format lunisolar calendars
Commit 86c8a57794 caused one regression in
test/intl402/DateTimeFormat. It is expected that Intl.DateTimeFormat and
Temporal produce consistent results.

Due to the píngqì approximation implemented in icu4x, it actually does
not totally align with icu4c for lunisolar calendars at extreme dates.
Ideally, icu4x will one day support all Intl.DateTimeFormat operations
as well. But for now, the fix is to create a custom icu::Calendar class
for lunisolar calendars that pipes calculations to icu4x.
2026-03-12 17:29:59 -05:00
Timothy Flynn
86c8a57794 LibJS+LibUnicode: Use icu4x for Temporal calendar operations
Replace the icu4c-based calendar implementation with one built on the
icu4x Rust crate (icu_calendar).

The icu4c API does not expose the píngqì month-assignment algorithm
used by the Chinese and Dangi lunisolar calendars. Our old code had to
approximate this by walking months via epoch millisecond arithmetic and
manually tracking leap month positions, which produced incorrect month
codes and ordinal month numbers for certain years. The icu4x calendar
crate handles píngqì natively.

With this patch, which is almost a 1-to-1 mapping of ICU invocations, we
pass 100% of all Temporal test262 tests.

The end goal might be to use icu4x for all of our ICU needs. But it does
not yet provide the APIs needed for all ECMA-402 prototypes.
2026-03-11 07:09:57 -04:00
Timothy Flynn
dc381c4ba7 LibUnicode: Preserve original ICU pattern in CalendarPattern
When AdjustDateTimeStyleFormat determines that no adjustment is needed
(no conflicting fields), the original date/time style pattern should be
used as-is for Temporal type formatting. Previously, the CalendarPattern
was round-tripped through ICU, which apparently can produce a different
pattern than the original result.
2026-03-09 19:02:59 +01:00
Timothy Flynn
b6699d439a LibUnicode: Add a cache for ICU calendar objects
Analogous to our existing locale and time zone caches.
2026-03-09 11:40:59 +01:00
Timothy Flynn
49b09b3fbe LibJS+LibUnicode: Always format zoned minutes and seconds with 2 digits
This matches the behavior of other engines.
2026-03-09 11:40:59 +01:00
InvalidUsernameException
1b2bca7831 LibUnicode: Print error codes when calls to ICU fail
Primary motivation for this change is the `VERIFY(icu_success(status))`
line in `Segmenter::create()` that was failing on multiple systems and
where we had to ask people to apply a patch to even know what the error
was.

Since this seems to be a recurring problem, let's just add a little
helper function and print the error codes returned by library calls.
2026-02-21 16:55:36 -05:00
Timothy Flynn
ee01f857d1 LibJS+LibUnicode: Port Intl.DateTimeFormat to UTF-16 strings 2025-07-24 10:39:52 +02:00
Viktor Szépe
19f88f96dc Everywhere: Fix typos - act III 2025-06-16 14:20:48 +01:00
Timothy Flynn
85b424464a AK+Everywhere: Rename verify_cast to as
Follow-up to fc20e61e72.
2025-01-21 11:34:06 -05:00
Timothy Flynn
93712b24bf Everywhere: Hoist the Libraries folder to the top-level 2024-11-10 12:50:45 +01:00
Renamed from Userland/Libraries/LibUnicode/DateTimeFormat.cpp (Browse further)