@ljharb, @bterlson, @littledan
/cc @xiaoyinl
The engines disagree with each other over how to format negative years in Date.prototype.toString()
See test case:
## Source
let year1BC = new Date("0001-10-13T05:16:33Z");
let year11BC = new Date("0001-10-13T05:16:33Z");
year1BC.setFullYear(-1, 10, 13);
year11BC.setFullYear(-11, 10, 13);
print(year1BC.toString());
print(year11BC.toString());
print(year1BC.toUTCString());
print(year11BC.toUTCString());
โโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ d8 โ Sat Nov 13 -001 22:16:33 GMT-0800 (Pacific Standard Time) โ
โ jsc โ Mon Nov 13 -011 22:16:33 GMT-0800 (Pacific Standard Time) โ
โ โ Sun, 14 Nov -001 06:16:33 GMT โ
โ โ Tue, 14 Nov -011 06:16:33 GMT โ
โโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ sm โ Sat Nov 13 -0001 22:16:33 GMT-0800 (Pacific Standard Time) โ
โ โ Mon Nov 13 -0011 22:16:33 GMT-0800 (Pacific Standard Time) โ
โ โ Sun, 14 Nov -0001 06:16:33 GMT โ
โ โ Tue, 14 Nov -0011 06:16:33 GMT โ
โโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ ch โ Sat Nov 13 -1 22:16:33 GMT-0800 (Pacific Standard Time) โ
โ โ Mon Nov 13 -11 22:16:33 GMT-0800 (Pacific Standard Time) โ
โ โ Sun, 14 Nov 2 B.C. 06:16:33 GMT โ
โ โ Tue, 14 Nov 12 B.C. 06:16:33 GMT โ
โโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
In Microsoft/ChakraCore#4067 we are addressing the fact that ChakraCore does not pad the year with leading 0's and uses B.C. instead of a negative year. However the spec versus current plurality implementation seems to be unclear.
In our opinion (ChakraCore), SpiderMonkey's output is more true to the spec text.
@xiaoyinl at https://github.com/Microsoft/ChakraCore/pull/4067#issuecomment-345651062 writes:
Section 20.3.4.43 specifies the exact format of
toUTCString(). It says:
- Let year be the String representation of YearFromTime(tv), formatted as a number of at least four digits, padded to the left with zeroes if necessary.
Because the spec reads that the year should be (emphasis mine):
formatted as a number of at least four digits, padded to the left with zeroes if necessary.
Thus the spec seems to imply the digits should be treated separately (by padding the absolute value of the year out to 4 digits) and then if the year was negative, inserting a - before it.
As I wrote in https://github.com/Microsoft/ChakraCore/pull/4067#issuecomment-345914246:
jsc and d8 behave as
printfformatting a negative number withprintf("%04d", negativeNumber);, which forint negativeNumber = -3;would print-003. (Java'sString.formatalso agrees with that interpretation of%04dwith a negative argument.)
This is what
d8andjschave done in terms of output, and I'd imagine that the implemented the formatting behavior with something akin tosprintfinstead of rolling their own as we've done here.
See discussion here:
https://github.com/Microsoft/ChakraCore/pull/4067#issuecomment-342685858
https://github.com/Microsoft/ChakraCore/pull/4067#issuecomment-345914246
Before the recent specification, there was disagreement for positive year padding. I changed to the 2/4 semantics, disagreeing with Edge and V8 semantics. IIRC I implemented and shipped this change in V8; I haven't seen any compat bug reports, but maybe @natorion has. If there are no compat issues for that change, I bet you're safe for choosing the SM option here too.
Okay, good to know about safety. However, still wondering if we can clarify the spec text so that there is a normative "correct" format, or explicitly allow certain differences in implementation like this (which seems less good than a single correct format).
For completeness of this discussion, here's current state of formatting positive years:
## Source
let year1 = new Date("0001-10-13T05:16:33Z");
let year11 = new Date("0011-10-13T05:16:33Z");
print(year1.toString());
print(year11.toString());
print(year1.toUTCString());
print(year11.toUTCString());
โโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ d8 โ Fri Oct 12 0001 22:16:33 GMT-0700 (Pacific Daylight Time) โ
โ jsc โ Wed Oct 12 0011 22:16:33 GMT-0700 (Pacific Daylight Time) โ
โ sm โ Sat, 13 Oct 0001 05:16:33 GMT โ
โ โ Thu, 13 Oct 0011 05:16:33 GMT โ
โโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ ch โ Fri Oct 12 1 22:16:33 GMT-0700 (Pacific Daylight Time) โ
โ โ Wed Oct 12 11 22:16:33 GMT-0700 (Pacific Daylight Time) โ
โ โ Sat, 13 Oct 1 05:16:33 GMT โ
โ โ Thu, 13 Oct 11 05:16:33 GMT โ
โโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Microsoft/ChakraCore#4067 will bring us in line with the current web reality for formatting positive years so that we have 4/4 agreement.
I think you should go for it and specify one of the options normatively! No strong opinion on which one you choose, but it's be great if the spec change/clarification came with test262 tests and an implementation in some engine that didn't have those semantics before. Apologies for my omission of this case previously.
The spec. should also be explicit about the handling of the minus sign for negative years.
I think the thing that makes most sense is 0 padding to 4 digits for year absolute values < 1000 and for negative years to explicit prepend a "-" to the (possibly padded) year.
@allenwb That is our opinion as well.
Can someone help by preparing a PR to make the appropriate changes for this issue?
cc @gibson042 @jungshik @FrankYFTang @sffc @apaprocki
Most helpful comment
The spec. should also be explicit about the handling of the minus sign for negative years.
I think the thing that makes most sense is 0 padding to 4 digits for year absolute values < 1000 and for negative years to explicit prepend a "-" to the (possibly padded) year.