Open qcyblm opened 2 years ago
When you specify a calendar, you can only see the actual calendar time if you write out the parameters separately
const data = Temporal.Now.zonedDateTimeISO('Asia/Shanghai').withCalendar("chinese")
console.log(data.toString());
// 2022-08-09T09:49:41.945660009+08:00[Asia/Shanghai][u-ca=chinese]
console.log( data.year,data.month,data.day );
// 2022 7 12
``` js
You can also use toLocaleString()
on any Temporal object. The parameters are the same as Date.prototype.toLocaleString
. Example:
zdt = Temporal.Now.zonedDateTime('chinese', 'Asia/Shanghai');
zdt.toLocaleString(
"zh-u-ca-chinese-nu-hanidec",
{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"numeric",second:"numeric",timeZoneName:"long"});
// '七月一二日 中国标准时间 一一:五二:一四'
@justingrant The lack of year
@qcyblm The root cause is of the problem is that the Intl.DateTimeFormat.prototype.resolvedOptions()
method drops the year
. We rely on that method in the polyfill. Because the output is the same in Chrome and Firefox, I suspect that the problem is in the upstream CLDR data that Intl.DateTimeFormat
uses to power its behavior.
@sffc, is this a CLDR bug, and if so could we get your help to file an issue in the right place(s) to fix it?
locale = 'zh-u-ca-chinese-nu-hanidec';
formattingProps = {year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"numeric",second:"numeric",timeZoneName:"long"};
date = new Date('2020-01-01T00:00:00Z');
dtf = new Intl.DateTimeFormat(locale, formattingProps);
original = dtf.format(date);
ro = dtf.resolvedOptions();
// {"locale":"zh-u-ca-chinese-nu-hanidec","calendar":"chinese","numberingSystem":"hanidec","timeZone":"America/Los_Angeles","hourCycle":"h23","hour12":false,"month":"long","day":"numeric","hour":"numeric","minute":"2-digit","second":"2-digit","timeZoneName":"long"}
// note that `ro.year` is missing, which causes the unexpected behavior below
dtfNew = new Intl.DateTimeFormat(locale, ro);
usingResolvedOptions = dtfNew.format(date);
console.log(JSON.stringify({original, usingResolvedOptions}));
// expected: both strings are the same
// actual:
// {
// "original": "二〇一九己亥年腊月六 北美太平洋标准时间 一六:〇〇:〇〇",
// "usingResolvedOptions": "腊月六日 北美太平洋标准时间 一六:〇〇:〇〇"
// }
``
In Temporal: .year
returns the arithmetic year; .eraYear
returns the year within the era.
In CLDR: Formatting of the chinese calendar uses the cyclic year field in CLDR patterns.
Does it work as expected if the DTF option is { dateStyle: "full" }
? If it only breaks when { year: "numeric", month: "long", day: "numeric" }
is used, then this would be (yet another) bug in the components bag resolution in either ICU or ECMA-402.
@qcyblm: Please post a test case with the expected result (a line of code that does not behave as expected, with how you expect it to behave).
Does it work as expected if the DTF option is
{ dateStyle: "full" }
?
The output using { dateStyle: "full" }
is below. Both strings are different from the output when each component is listed separately in https://github.com/tc39/ecma402/issues/703.
{
"original": "二〇一九己亥年腊月初六星期二",
"usingResolvedOptions":"二〇一九己亥年腊月初六星期二"
}
@qcyblm: Please post a test case with the expected result (a line of code that does not behave as expected, with how you expect it to behave).
Note that the code in the test case should not use Temporal but should use Intl.DateTimeFormat.prototype.format
because that seems to be the underlying issue here. Using Temporal would just distract from the real bug.
This sounds similar to https://bugzilla.mozilla.org/show_bug.cgi?id=1298794 (upstream: https://unicode-org.atlassian.net/browse/ICU-13518). But in addition to that round tripping issue, we also have a "related year" component here. I know that the SpiderMonkey implementation doesn't map the Date Field Symbol r
when computing the resolved options, but I can't remember anymore if that's intentional or just an oversight.
Okay, I've just tested this. Handling r
fixes the output, now I have to somehow verify that that's actually spec-compliant and won't introduce any other bugs...
Yes, if the issue is only that resolvedOptions doesn't round-trip, then the bug is probably around failing to match alternative year fields in the resolved pattern. There are 5 year fields listed in UTS 35: YyUur. https://www.unicode.org/reports/tr35/tr35-dates.html#dfst-year
I transferred the issue to the ECMA-402 repository. I think we should at least add a test for the behavior, if not clarify the spec.
There are 5 year fields listed in UTS 35: YyUur.
I wonder how to map standalone U
, because the year
property for resolvedOptions()
can only be either "2-digit"
or "numeric"
.
js> new Intl.DateTimeFormat("de-u-ca-chinese", {year:"numeric"}).format()
"ren-yin"
js> new Intl.DateTimeFormat("de-u-ca-chinese", {year:"numeric"}).resolvedOptions()
Object { locale: "de-u-ca-chinese", calendar: "chinese", numberingSystem: "latn", timeZone: "Europe/Berlin" }
Note that adding {year: "numeric"}
to the resolvedOptions seems to make the pattern round-trip. I think we should just do that when relatedYear is in the output.
Writing short PR to do the above.
Such as
new Date().toLocaleString()