tc39/ecma402

Cyclic year doesn't show up in resolvedOptions

sffc opened this issue · 1 comments

sffc commented

In CreateDateTimeFormat, it says:

  1. For each row in Table 7, except the header row, in table order, do
    a. Let prop be the name given in the Property column of the row.
    b. If bestFormat has a field [[<prop>]], then
    i. Let p be bestFormat.[[<prop>]].
    ii. Set dateTimeFormat's internal slot whose name is the Internal Slot column of the row to p.

In Table 7, the year is stated as being either "numeric" or "2-digit". However, this is clearly not reflected in the Chinese calendar resolvedOptions, which uses r and U (related Gregorian and cycle year name):

new Intl.DateTimeFormat("en", { calendar: "chinese", year: "numeric" }).format(new Date())
// '2023(gui-mao)'
new Intl.DateTimeFormat("en", { calendar: "chinese", year: "numeric" }).resolvedOptions()
// {locale: 'en', calendar: 'chinese', numberingSystem: 'latn', timeZone: 'America/Los_Angeles'}

It works fine in formatToParts:

0: {type: 'relatedYear', value: '2023'}
1: {type: 'literal', value: '('}
2: {type: 'yearName', value: 'gui-mao'}
3: {type: 'literal', value: ')'}
anba commented

Per 11.2.3 Internal slots, "{relatedYear}" can only appear in a pattern string when the format record has a [[year]] field. And if a [[year]] field is present, CreateDateTimeFormat will set the Intl.DateTimeFormat's [[Year]] field to the format records [[year]] value. Intl.DateTimeFormat.prototype.resolvedOptions should then return the value of the [[Year]] internal slot.

IOW this seems to be spec'ed correctly, it's just that engines don't implement this correctly.

As long as the pattern string can't contain both "{year}" and "{relatedYear}", engines simply have to map the 'r' and 'U' Date Field Symbols to year: "numeric". (The related-year can only be "numeric", never "2-digit".)