Repository navigation
fix(utils): read back calendar text in Latvian, Amharic and Hindi - #9840
nynexman4464 wants to merge 7 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
AI review status for this pull request.
|
There was a problem hiding this comment.
Approval waits on an engineering owner's spec decision: these parser changes rest on spec:AST-111 FR9, FR10 and FR13, which are still draft and not on main, where the internationalization architecture (INV10) keeps date parsing Gregorian.
The decision needs to cover these choices:
1. adarsreads as day 1 of Adar when no other number in the text can be the day.- Where the short era reorders a format's fields and the narrow era does not, the narrow era is written for every date: every Amharic era-calendar hint (
1/1/8 R,23/2/2019 AM) and the same hints in about 25 other languages, such as Turkmen02.11.2569→2.11.2569 BE. - Where every era width reorders the fields, a date before the latest era gets the short era at one end of the text, such as Amharic
1 ጃን 12 BROC; this also changes committed text in other locales, such as ColognianBROC 1. Jan. 12.
An engineering owner records the decision by commenting /approve-spec <full head SHA> on this pull request, and the author may do so if they are an engineering owner; otherwise this waits until AST-111 is current on main.
- Non-blocking: the description says no committed text and no other locale changes, but against the base the Amharic
datetext gains the era for earlier-era dates (1 ጃን 33→1 ጃን 33 Meiji) and both era rules reach locales outside the 34 compared; please correct it so the decision covers them.
[Automated review]
| // When every era width reorders the fields, such as the Amharic short-month | ||
| // date, the text has no era. Text without an era reads in the latest era, | ||
| // so a date of an earlier era adds it on the side where the era format has | ||
| // it. |
There was a problem hiding this comment.
Non-blocking (comment style): the second sentence is 27 words and joins two topics. A shorter form that keeps the reason: "Text without an era reads in the latest era. So a date of an earlier era adds the era. It goes at the start or the end, as in the era format."
96920a3 to
f81d686
Compare
39fd607 to
2ab4887
Compare
There was a problem hiding this comment.
Approval waits on an engineering owner's spec decision: these parser changes rest on spec:AST-111 FR9, FR10 and FR13, which are still draft and not on main, where the internationalization architecture (INV10) keeps date parsing Gregorian.
The decision needs to cover these choices:
1. adarsreads as day 1 of Adar when no other number in the text can be the day.- In the Japanese and Minguo calendars, a hint whose short era reorders the fields and whose narrow era does not shows the narrow era for every date, in 30 locales (Amharic
2/11/8→2/11/8 R, Turkmen02.11.8→2.11.8 R). - In those calendars, where every era width reorders the fields, only a date before the latest era gets the short era at one end (Colognian
1. Jan. 12→BROC 1. Jan. 12), in 104 locales; a current-era date keeps no era, while draft FR10 says such a format gains it.
An engineering owner records the decision by commenting /approve-spec <full head SHA> on this pull request, and the author may do so if they are an engineering owner; otherwise this waits until AST-111 is current on main.
- Non-blocking: the description still says the other Amharic hints gain an era (
23/2/2019 AM) and that no committed text or other locale changes, but now only Japanese and Minguo text changes, including committed text in 103 locales such as Amharic and Colognian; please update it so the decision covers what the pull request does.
[Automated review]
| * the fields. Where the era changes, a narrow era that keeps the order is | ||
| * used instead, such as Amharic Japanese "1/1/8 R". |
There was a problem hiding this comment.
Non-blocking (comment style): "a narrow era that keeps the order is used instead" is passive. An active form: "Where the era changes, it uses a narrow era that keeps the order instead, such as Amharic Japanese "1/1/8 R"."
f81d686 to
18150b8
Compare
2ab4887 to
4c881d8
Compare
There was a problem hiding this comment.
Approval waits on an engineering owner's spec decision: these parser changes rest on spec:AST-111 FR9, FR10 and FR13, which are still draft and not on main, where the internationalization architecture (INV10) keeps date parsing Gregorian.
The decision needs to cover these choices:
1. adarsreads as day 1 of Adar when no other number in the text can be the day.- In the Japanese and Minguo calendars, a hint whose short era reorders the fields and whose narrow era does not shows the narrow era for every date, in 30 locales (Amharic
2/11/8→2/11/8 R, Turkmen02.11.8→2.11.8 R). - In those calendars, where every era width reorders the fields, only a date before the latest era gets the short era at one end (Colognian
1. Jan. 12→BROC 1. Jan. 12), in 104 locales; a current-era date keeps no era, while draft FR10 says such a format gains it.
An engineering owner records the decision by commenting /approve-spec <full head SHA> on this pull request, and the author may do so if they are an engineering owner; otherwise this waits until AST-111 is current on main.
[Automated review]
18150b8 to
f02913f
Compare
4c881d8 to
be112b6
Compare
|
/approve-spec be112b6 |
There was a problem hiding this comment.
Approved: an engineering owner approved spec:AST-111 FR9, FR10 and FR13 for this head with /approve-spec, and the parser changes match them. The new round-trip cases for Latvian month names that start with a number, Japanese and Minguo dates of an earlier era, and the Hindi Buddhist hint fail before the change and pass after it. CI's test workflows run only for pull requests into main, so they have not run on this head; they run when the calendar-parser branch goes to main.
[Automated review]
f02913f to
e38dac1
Compare
be112b6 to
8427f88
Compare
There was a problem hiding this comment.
Approval waits on an engineering owner's spec decision at this head: these parser changes rest on spec:AST-111 FR9, FR10 and FR13, which are still draft on main, and the earlier /approve-spec named the previous head, so it does not carry over to this rebased head. The decision covers the same three choices as before:
1. adarsreads as day 1 of Adar when no other number in the text can be the day.- In the Japanese and Minguo calendars, the narrow era is written for every date where the short era reorders the fields, such as Amharic
2/11/8→2/11/8 Rand Asturian1/1/12→1/1/12 A.R.D.C.. - Where every era width reorders the fields, only a date before the latest era gains the short era at one end, such as Colognian
1. Jan. 12→BROC 1. Jan. 12.
An engineering owner records the decision by commenting /approve-spec <full head SHA> on this pull request (the author may do so as an engineering owner), or AST-111 moves to current on main. No other issue was found.
[Automated review]
e38dac1 to
0d0e06d
Compare
8427f88 to
4d2cb31
Compare
There was a problem hiding this comment.
Approval waits on an engineering owner's spec decision, and one parser fix is needed first.
- Spec decision: these parser changes rest on
spec:AST-111FR9, FR10 and FR13, which are still draft onmain, and the earlier/approve-specnamed a previous head, so the decision is needed again for the1. adarsday reading, the narrow era where the short era reorders the fields (such as Amharic2/11/8→2/11/8 R), and the short era on earlier-era dates where every era width reorders them (such as Colognian1. Jan. 12→BROC 1. Jan. 12). - Miss:
calendarDateParser.tsline 714 counts a two-digit year as a possible day, so Latvian Hebrew86. g. 1. adars, which reads as 1 Adar 5786 on the base, is now unreadable; counting only numbers up to 31 fixes it, and that input belongs in the per-date tests.
The fix makes a new head. An engineering owner then records the decision by commenting /approve-spec <full head SHA> on this pull request for that head, and the author may do so as an engineering owner. Making AST-111 current on main also settles it.
[Automated review]
| } | ||
| // Latvian "1. adars" is a month, and also day 1 of "adars". It is the day | ||
| // when no other number can be the day. | ||
| if (hasDigitName && !out.some(t => t.t === 'num' && t.v.length <= 2)) { |
There was a problem hiding this comment.
Miss: this counts a two-digit year as a possible day. Latvian Hebrew 86. g. 1. adars reads as 1 Adar 5786 on the base, and on this head it is unreadable (Adar I with day 86). Counting only numbers that can be a day keeps the stated rule:
if (
hasDigitName &&
!out.some(t => t.t === 'num' && t.v.length <= 2 && Number(t.v) <= 31)
) {0d0e06d to
ce48c99
Compare
4d2cb31 to
4ffa79b
Compare
|
/approve-spec 4ffa79b |
There was a problem hiding this comment.
Changes requested: one parser fix is needed before this can be approved.
- Miss:
calendarDateParser.ts:711counts a two-digit year of 31 or less as a possible day, so typed Latvian Hebrew26. g. 1. adarsreads as 26 Adar I 5787 (5 March 2027) instead of 1 Adar 5726 (21 February 1966) as on the base; treat a number followed by the locale's year word (g.) as the year and add this case to the per-date tests.
The era and separator changes cause no read-back regression in the sampled texts, and spec:AST-111 FR9, FR10 and FR13 were accepted for this head. A new commit invalidates that acceptance, so an engineering owner (the author may, as one) records /approve-spec <full head SHA> again on the head that carries the fix.
[Automated review]
| } | ||
| // Latvian "1. adars" is a month, and also day 1 of "adars". It is the day | ||
| // when no other number can be the day. | ||
| if (hasDigitName && !out.some(t => t.t === 'num' && Number(t.v) <= 31)) { |
There was a problem hiding this comment.
Miss: a two-digit year of 31 or less still counts as a possible day here. Typed Latvian Hebrew 26. g. 1. adars reads as 26 Adar I 5787 (5 March 2027); the base reads 1 Adar 5726 (21 February 1966). 05. g. 1. adars and 10. g. 1. adars move the same way, and 31. g. 1. adars is rejected. A number followed by the locale's year word (g., the literal after the year in its own formats) is the year, so it should not count:
if (hasDigitName && !out.some(t => t.t === 'num' && !t.isYear && Number(t.v) <= 31)) {Please add 26. g. 1. adars to the per-date cases.
ce48c99 to
295c13c
Compare
4ffa79b to
2f262b5
Compare
|
/approve-spec 2f262b5 |
There was a problem hiding this comment.
Changes requested: one parser fix is needed before this can be approved.
- Miss:
calendarDateParser.ts:711still counts a two-digit year of 31 or less as a possible day, so typed Latvian Hebrew26. g. 1. adarsreads as 26 Adar I 5787 (5 March 2027) instead of 1 Adar 5726 (21 February 1966) as on the base; treat a number followed by the locale's year word (g.) as the year and add this case to the per-date tests.
The era and separator changes cause no read-back regression in the sampled texts, and spec:AST-111 FR9, FR10 and FR13 are accepted for this head. A new commit needs that acceptance again, so an engineering owner (the author may, as one) comments /approve-spec <full head SHA> on the head that carries the fix.
[Automated review]
Month names that start with a number in Latvian Hebrew and Hijri dates, Minguo and Japanese dates of an earlier era in Amharic, and the Hindi Buddhist format hint do not read back as the same date.
Read a month name that starts with a number, and read it as a day and a month when no other number can be the day. Accept the separators of the locale's own numeric pattern, and fold a backtick in ASCII text as in other text. When the era would reorder the fields, write it beside them for a date of an earlier era.
When a locale's numeric pattern has no era and the short era reorders the fields, try the narrow era and use it if it keeps the locale's order. Amharic format hints then always show the era, such as 1/1/8 R in the Japanese calendar, so the text reads back in the right era. Formats where every era width reorders the fields keep the earlier-era step.
The narrow-era fallback and the earlier-era suffix now apply only to calendars whose era of 1900-01-01 differs from that of 2100-12-31, which Intl reports for `japanese` and `roc`. Single-era calendars write the same text as on the base. The display text comes from `format()` again: its spaces can differ from the joined `formatToParts()` values, such as before the Bulgarian and Russian year suffix.
Only a number up to 31 can be the day, so Latvian Hebrew "86. g. 1. adars" reads as 1 Adar 5786 again.
Latvian Hebrew "26. g. 1. adars" reads as 1 Adar 5726 again. The parser
learns the year word ("g.", "gada") from the literal that follows the year.
2f262b5 to
4c8a492
Compare
|
/approve-spec 4c8a492 |
User impact
The calendar date parser must read back the text it writes: the committed text and the format hint (
spec:AST-111FR13). In these cases it cannot:lv-LV), Hebrew and all three Hijri calendars: some month names start with a number. Examples are1. adars(Adar I),2. adars(Adar II),1. rabīand2. džumādā. The parser reads the number as a day, so5660. g. 2. 1. adars AMis unreadable.roc) calendars, where the locale's pattern omits the era: a year without its era reads in the latest era. Amharic1/1/12(1 January 1900, 12 years before the Minguo era) reads as 1923.1/1/33(Meiji 33) reads as Reiwa 33, which is 2051.hi-IN), Buddhist format hint: the CLDR pattern has a stray backtick, so the hint is1/1`/2443 बौद्ध संवत. The parser needs one separator between all the numbers, so the hint is unreadable.The parser is internal, and no public API changes.
Problem and solution fit
Réb. 1. But the tokenizer reads a digit as a number before it looks for a name. Now it looks for a known name at a digit too.1. adarsis also day 1 ofadarsin a common year, so the parser reads it as the day when no other number in the text can be the day. Only a number up to 31 can be the day, so a two-digit year does not count: Latvian Hebrew86. g. 1. adarsreads as 1 Adar 5786. A number before the locale's year word is the year, not a possible day. The lexicon learns the year words from the literal that follows the year in the locale's own formats (g.andgadainlv), so26. g. 1. adarsreads as 1 Adar 5726.japaneseandrocwhere the locale's pattern omits the era. A year needs its era only in a calendar whose era changes within the supported range. The formatter derives this fromIntl: the era of 1900-01-01 differs from the era of 2100-12-31. On current engines that isjapanese(Meiji to Reiwa) androc(before Minguo to Minguo). No calendar list decides this. In those two calendars only:1/1/8 Rand Turkmen1.1.12 BROC. The lexicon reads the narrow names because it learns era names from the same display options.BROC 1. Jan. 12and Amharic1 ጃን 12 BROC. Dates in the latest era are unchanged.8/11/1405 AP, and no era otherwise, as in Turkmen Buddhist02.11.2569and Amharic Ethiopic23/4/2018. Their text is the same as on the base.Expected behavior and authority
spec:AST-111FR13 (draft): committed text and the format hint read back as the same date.spec:AST-111FR10 (draft) says ajapaneseorrocformat that omits the era gains it, written narrow when that keeps the field order; where every era width reorders the fields, only a date before the latest era gains it, because a year without an era reads in the latest era. The formatter does both.calendarDateParser.roundtrip.test.tschecks FR13. This change adds the locales above to it.Smallest restoration
calendarDateParser.tsonly: one tokenizer step with a fallback, two learned lexicon sets (separators and year words), one derived era-change check, a narrow-era fallback in the display options, and an earlier-era suffix beside it in the formatter. There are no per-locale or per-calendar rules. The text still goes through Core'splainDateFormatandplainDateFormatToParts, as on the base.Output changes against the base
Comparison of the base and this branch over every locale that both CLDR 48 lists and
Intl.DateTimeFormat.supportedLocalesOfaccepts (662), in all 16 calendars, with every 331st day from 1900 through 2100 plus the era boundaries (233 dates), in the hint and the three committed formats: 9,860,560 texts.japaneseandroc. No text in any other calendar changes.1/1/33→1/1/33 M, Turkmen01.01.12→1.1.12 BROC, Asturian1/1/12→1/1/12 A.R.D.C..1/1/12→BROC 1/1/12), thedatetext in 55 locales (Colognian1. Jan. 12→BROC 1. Jan. 12), thedate_longtext in 4 and thedate_weekdaytext in 101.date_weekdaytexts (and thedatetext inbas,duaanddyo) that did not read back on the base and still do not. In 48 of those 53 locales the base cannot read back the latest-era Japanese weekday text either, so the cause is the weekday and month words, not the era. No text that read back on the base fails now.ja,en,zh-Hantandth. The parser-side fixes forlv-LVandhi-INchange no output.mynumeric non-Gregorian date format, on the base too.myis compared in Gregorian, ISO and the lunisolar calendars only.Evidence
"5660. g. 2. 1. adars AM" -> unreadable,"1318. g. 3. 1. rabī AH" -> unreadable,"1/1/12" -> 1923-01-01,"1/1/33" -> 2051-01-01,"1/1`/2443 बौद्ध संवत" -> unreadable.lv-LV,am-ETandhi-IN, with every seventh day from 1900 through 2100 (every 41st day forchineseanddangi), finds no failures. Dates before 1900 are best effort.fa-IRPersian hint is still۱۴۰۵/۸/۱۱. Latvian5661. g. 1. adarsis still 1 Adar 5661 (20 February 1901),86. g. 1. adarsis still 1 Adar 5786 (18 February 2026), and26. g. 1. adarsis still 1 Adar 5726 (21 February 1966), as on the base.1. adarscase that guards the day fallback,86. g. 1. adars, which fails when a two-digit year counts as a possible day, and26. g. 1. adars, which reads as 26 Adar I 5787 (5 March 2027) when a number before the year word counts as a possible day. The matrix addslv-LVfor Hebrew and the Hijri calendars,am-ETforrocandjapanese, andhi-INfor Buddhist. The focused test reads backam-ETand Colognian (ksh) dates in the current and earlier eras, checks the narrow era in the hint (1/1/8 R,1/1/2 H), and checks that single-era hints get no era (Amharic Ethiopic23/4/2018, Turkmen Buddhist02.11.2569).Scope
Testing
pnpm exec vitest run --maxWorkers=2over the parser's test files (unit and round trip) plusdocPropLiterals.test.ts: 3 files, 96 tests pass. CI runs the full suites.pnpm exec tsc --noEmitinpackages/core: passes.pnpm check:knowledgeandpnpm check:changesets: pass.node scripts/pre-review.mjs --base origin/main: 204 authored lines.Writing rubric results
No knowledge record is touched.