Просмотр исходного кода

Make Date.to(UTC)String() outputs match web reality and spec language

1. If the absolute value of the year is less than 1000, pad it to 4 digits
2. For a BC year, output negative year, rather than positive year + "B.C."

Some tests in DateParse2.js fail due to the second change. They will be re-enabled
after #4178 is fixed.
Xiaoyin Liu 8 лет назад
Родитель
Сommit
3db89831b7

+ 5 - 4
lib/Runtime/Library/DateImplementation.cpp

@@ -402,14 +402,15 @@ namespace Js {
         bs->AppendChars(_u(' '));
 
         // Add the year.
-        if (pymd->year > 0)
+        if ((pymd->year) > 0)
         {
-            bs->AppendChars(pymd->year, 10, ConvertLongToString);
+            bs->AppendChars(pymd->year, 10, ConvertUInt32ToString_ZeroPad_4);
         }
         else
         {
-            bs->AppendChars(1 - pymd->year, 10, ConvertLongToString);
-            bs->AppendChars(_u(" B.C."));
+            int positiveYear = -(pymd->year); // pymd->year is negative
+            bs->AppendChars(_u('-'));
+            bs->AppendChars(positiveYear, 10, ConvertUInt32ToString_ZeroPad_4);
         }
 
         // Add the time.

+ 44 - 1
lib/Runtime/Library/DateImplementation.h

@@ -382,6 +382,40 @@ namespace Js {
         return GetDateDefaultString<StringBuilder>(&ymd, &tzd, DateTimeFlag::None, scriptContext, newStringBuilder);
     }
 
+    const auto ConvertUInt32ToString_ZeroPad_4 = [](const uint32 value, char16 *const buffer, const CharCount charCapacity)
+    {
+        Assert(charCapacity >= 4);
+        if (value < 10)
+        {
+            buffer[0] = _u('0');
+            buffer[1] = _u('0');
+            buffer[2] = _u('0');
+            buffer[3] = static_cast<char16>(value + _u('0'));
+            buffer[4] = 0;
+        }
+        else if (value < 100)
+        {
+            buffer[0] = _u('0');
+            buffer[1] = _u('0');
+            buffer[2] = static_cast<char16>((value / 10) + _u('0'));
+            buffer[3] = static_cast<char16>((value % 10) + _u('0'));
+            buffer[4] = 0;
+        }
+        else if (value < 1000)
+        {
+            buffer[0] = _u('0');
+            buffer[1] = static_cast<char16>((value / 100) + _u('0'));
+            buffer[2] = static_cast<char16>(((value / 10) % 10) + _u('0'));
+            buffer[3] = static_cast<char16>((value % 10) + _u('0'));
+            buffer[4] = 0;
+        }
+        else
+        {
+            const errno_t err = _ultow_s(value, buffer, charCapacity, 10);
+            Assert(err == 0);
+        }
+    };
+
     //
     // Get default date string, shared with hybrid debugging.
     //  StringBuilder: A Js::StringBuilder/CompoundString like class, used to build strings.
@@ -418,7 +452,16 @@ namespace Js {
             bs->AppendChars(_u(' '));
 
             // year is directly after day, month, daydigit for IE11+
-            bs->AppendChars(pymd->year, 10, ConvertLongToString);
+            if ((pymd->year) > 0)
+            {
+                bs->AppendChars(pymd->year, 10, ConvertUInt32ToString_ZeroPad_4);
+            }
+            else
+            {
+                int positiveYear = -(pymd->year); // pymd->year is negative
+                bs->AppendChars(_u('-'));
+                bs->AppendChars(positiveYear, 10, ConvertUInt32ToString_ZeroPad_4);
+            }
 
             if(!(noDateTime & DateTimeFlag::NoTime))
             {

+ 3 - 2
test/Date/DateParse2.js

@@ -8,7 +8,8 @@
 myPrint("A --");
 testDate(new Date(-2012, 1, 2, 1, 2, 3));
 testParseDate(new Date(-2012, 1, 2, 1, 2, 3).toString());
-testParseDate(new Date(-2012, 1, 2, 1, 2, 3).toUTCString());
+// Disabled due to https://github.com/Microsoft/ChakraCore/issues/4300
+//testParseDate(new Date(-2012, 1, 2, 1, 2, 3).toUTCString());
 testParseDate(new Date(-2012, 1, 2, 1, 2, 3).toISOString());
 
 myPrint("B --");
@@ -26,7 +27,7 @@ testParseDate(new Date(99999, 1, 2, 1, 2, 3).toISOString());
 myPrint("D --");
 testDate(new Date(-99999, 1, 2, 1, 2, 3));
 testParseDate(new Date(-99999, 1, 2, 1, 2, 3).toString());
-testParseDate(new Date(-99999, 1, 2, 1, 2, 3).toUTCString());
+//testParseDate(new Date(-99999, 1, 2, 1, 2, 3).toUTCString());
 testParseDate(new Date(-99999, 1, 2, 1, 2, 3).toISOString());
 
 myPrint("E --");

+ 26 - 46
test/Date/DateParse2.v5.baseline

@@ -3,8 +3,8 @@ A --
 Date string:		Tue Feb 02 -2012 01:02:03 GMT-0800 (Pacific Standard Time)
 	 raw:		-125657017077000
 	 toString:	Tue Feb 02 -2012 01:02:03 GMT-0800 (Pacific Standard Time)
-	 toUTCString:	Tue, 02 Feb 2013 B.C. 09:02:03 GMT
-	 toGMTString:	Tue, 02 Feb 2013 B.C. 09:02:03 GMT
+	 toUTCString:	Tue, 02 Feb -2012 09:02:03 GMT
+	 toGMTString:	Tue, 02 Feb -2012 09:02:03 GMT
 	 toISOString:	-002012-02-02T09:02:03.000Z
 			2 -125657017077000 480
 			-2012/1/2
@@ -13,18 +13,8 @@ Date string:		Tue Feb 02 -2012 01:02:03 GMT-0800 (Pacific Standard Time)
 Date string:		Tue Feb 02 -2012 01:02:03 GMT-0800 (Pacific Standard Time)
 	 raw:		-125657017077000
 	 toString:	Tue Feb 02 -2012 01:02:03 GMT-0800 (Pacific Standard Time)
-	 toUTCString:	Tue, 02 Feb 2013 B.C. 09:02:03 GMT
-	 toGMTString:	Tue, 02 Feb 2013 B.C. 09:02:03 GMT
-	 toISOString:	-002012-02-02T09:02:03.000Z
-			2 -125657017077000 480
-			-2012/1/2
-			1:2:3.0
-
-Date string:		Tue, 02 Feb 2013 B.C. 09:02:03 GMT
-	 raw:		-125657017077000
-	 toString:	Tue Feb 02 -2012 01:02:03 GMT-0800 (Pacific Standard Time)
-	 toUTCString:	Tue, 02 Feb 2013 B.C. 09:02:03 GMT
-	 toGMTString:	Tue, 02 Feb 2013 B.C. 09:02:03 GMT
+	 toUTCString:	Tue, 02 Feb -2012 09:02:03 GMT
+	 toGMTString:	Tue, 02 Feb -2012 09:02:03 GMT
 	 toISOString:	-002012-02-02T09:02:03.000Z
 			2 -125657017077000 480
 			-2012/1/2
@@ -33,8 +23,8 @@ Date string:		Tue, 02 Feb 2013 B.C. 09:02:03 GMT
 Date string:		-002012-02-02T09:02:03.000Z
 	 raw:		-125657017077000
 	 toString:	Tue Feb 02 -2012 01:02:03 GMT-0800 (Pacific Standard Time)
-	 toUTCString:	Tue, 02 Feb 2013 B.C. 09:02:03 GMT
-	 toGMTString:	Tue, 02 Feb 2013 B.C. 09:02:03 GMT
+	 toUTCString:	Tue, 02 Feb -2012 09:02:03 GMT
+	 toGMTString:	Tue, 02 Feb -2012 09:02:03 GMT
 	 toISOString:	-002012-02-02T09:02:03.000Z
 			2 -125657017077000 480
 			-2012/1/2
@@ -126,8 +116,8 @@ D --
 Date string:		Fri Feb 02 -99999 01:02:03 GMT-0800 (Pacific Standard Time)
 	 raw:		-3217827999477000
 	 toString:	Fri Feb 02 -99999 01:02:03 GMT-0800 (Pacific Standard Time)
-	 toUTCString:	Fri, 02 Feb 100000 B.C. 09:02:03 GMT
-	 toGMTString:	Fri, 02 Feb 100000 B.C. 09:02:03 GMT
+	 toUTCString:	Fri, 02 Feb -99999 09:02:03 GMT
+	 toGMTString:	Fri, 02 Feb -99999 09:02:03 GMT
 	 toISOString:	-099999-02-02T09:02:03.000Z
 			2 -3217827999477000 480
 			-99999/1/5
@@ -136,18 +126,8 @@ Date string:		Fri Feb 02 -99999 01:02:03 GMT-0800 (Pacific Standard Time)
 Date string:		Fri Feb 02 -99999 01:02:03 GMT-0800 (Pacific Standard Time)
 	 raw:		-3217827999477000
 	 toString:	Fri Feb 02 -99999 01:02:03 GMT-0800 (Pacific Standard Time)
-	 toUTCString:	Fri, 02 Feb 100000 B.C. 09:02:03 GMT
-	 toGMTString:	Fri, 02 Feb 100000 B.C. 09:02:03 GMT
-	 toISOString:	-099999-02-02T09:02:03.000Z
-			2 -3217827999477000 480
-			-99999/1/5
-			1:2:3.0
-
-Date string:		Fri, 02 Feb 100000 B.C. 09:02:03 GMT
-	 raw:		-3217827999477000
-	 toString:	Fri Feb 02 -99999 01:02:03 GMT-0800 (Pacific Standard Time)
-	 toUTCString:	Fri, 02 Feb 100000 B.C. 09:02:03 GMT
-	 toGMTString:	Fri, 02 Feb 100000 B.C. 09:02:03 GMT
+	 toUTCString:	Fri, 02 Feb -99999 09:02:03 GMT
+	 toGMTString:	Fri, 02 Feb -99999 09:02:03 GMT
 	 toISOString:	-099999-02-02T09:02:03.000Z
 			2 -3217827999477000 480
 			-99999/1/5
@@ -156,35 +136,35 @@ Date string:		Fri, 02 Feb 100000 B.C. 09:02:03 GMT
 Date string:		-099999-02-02T09:02:03.000Z
 	 raw:		-3217827999477000
 	 toString:	Fri Feb 02 -99999 01:02:03 GMT-0800 (Pacific Standard Time)
-	 toUTCString:	Fri, 02 Feb 100000 B.C. 09:02:03 GMT
-	 toGMTString:	Fri, 02 Feb 100000 B.C. 09:02:03 GMT
+	 toUTCString:	Fri, 02 Feb -99999 09:02:03 GMT
+	 toGMTString:	Fri, 02 Feb -99999 09:02:03 GMT
 	 toISOString:	-099999-02-02T09:02:03.000Z
 			2 -3217827999477000 480
 			-99999/1/5
 			1:2:3.0
 
 E --
-Date string:		Tue Feb 02 -12 01:02:03 GMT-0800 (Pacific Standard Time)
+Date string:		Tue Feb 02 -0012 01:02:03 GMT-0800 (Pacific Standard Time)
 	 raw:		-62543113077000
-	 toString:	Tue Feb 02 -12 01:02:03 GMT-0800 (Pacific Standard Time)
-	 toUTCString:	Tue, 02 Feb 13 B.C. 09:02:03 GMT
-	 toGMTString:	Tue, 02 Feb 13 B.C. 09:02:03 GMT
+	 toString:	Tue Feb 02 -0012 01:02:03 GMT-0800 (Pacific Standard Time)
+	 toUTCString:	Tue, 02 Feb -0012 09:02:03 GMT
+	 toGMTString:	Tue, 02 Feb -0012 09:02:03 GMT
 	 toISOString:	-000012-02-02T09:02:03.000Z
 			2 -62543113077000 480
 			-12/1/2
 			1:2:3.0
 
-Date string:		Tue Feb 02 -12 01:02:03 GMT-0800 (Pacific Standard Time)
+Date string:		Tue Feb 02 -0012 01:02:03 GMT-0800 (Pacific Standard Time)
 	 raw:		-62543113077000
-	 toString:	Tue Feb 02 -12 01:02:03 GMT-0800 (Pacific Standard Time)
-	 toUTCString:	Tue, 02 Feb 13 B.C. 09:02:03 GMT
-	 toGMTString:	Tue, 02 Feb 13 B.C. 09:02:03 GMT
+	 toString:	Tue Feb 02 -0012 01:02:03 GMT-0800 (Pacific Standard Time)
+	 toUTCString:	Tue, 02 Feb -0012 09:02:03 GMT
+	 toGMTString:	Tue, 02 Feb -0012 09:02:03 GMT
 	 toISOString:	-000012-02-02T09:02:03.000Z
 			2 -62543113077000 480
 			-12/1/2
 			1:2:3.0
 
-Date string:		Tue, 02 Feb 13 B.C. 09:02:03 GMT
+Date string:		Tue, 02 Feb -0012 09:02:03 GMT
 	 raw:		NaN
 	 toString:	Invalid Date
 	 toUTCString:	Invalid Date
@@ -192,9 +172,9 @@ Date string:		Tue, 02 Feb 13 B.C. 09:02:03 GMT
 
 Date string:		-000012-02-02T09:02:03.000Z
 	 raw:		-62543113077000
-	 toString:	Tue Feb 02 -12 01:02:03 GMT-0800 (Pacific Standard Time)
-	 toUTCString:	Tue, 02 Feb 13 B.C. 09:02:03 GMT
-	 toGMTString:	Tue, 02 Feb 13 B.C. 09:02:03 GMT
+	 toString:	Tue Feb 02 -0012 01:02:03 GMT-0800 (Pacific Standard Time)
+	 toUTCString:	Tue, 02 Feb -0012 09:02:03 GMT
+	 toGMTString:	Tue, 02 Feb -0012 09:02:03 GMT
 	 toISOString:	-000012-02-02T09:02:03.000Z
 			2 -62543113077000 480
 			-12/1/2
@@ -295,8 +275,8 @@ Date string:		Tue Feb 02 2012 01:02:03 GMT+0430 (prisec@)
 Date string:		Tue Feb 2 01:02:03 PST 2013 B.C.
 	 raw:		-125657017077000
 	 toString:	Tue Feb 02 -2012 01:02:03 GMT-0800 (Pacific Standard Time)
-	 toUTCString:	Tue, 02 Feb 2013 B.C. 09:02:03 GMT
-	 toGMTString:	Tue, 02 Feb 2013 B.C. 09:02:03 GMT
+	 toUTCString:	Tue, 02 Feb -2012 09:02:03 GMT
+	 toGMTString:	Tue, 02 Feb -2012 09:02:03 GMT
 	 toISOString:	-002012-02-02T09:02:03.000Z
 			2 -125657017077000 480
 			-2012/1/2

+ 8 - 0
test/Date/rlexe.xml

@@ -140,4 +140,12 @@
       <files>TwoDigitYears.js</files>
     </default>
   </test>
+  <test>
+    <default>
+      <files>toStringAndToUTCStringYearPadding.js</files>
+      <!-- test is timezone-sensitive; remove exclude_jenkins after fix (Microsoft/ChakraCore#319) -->
+      <tags>exclude_jenkins</tags>
+      <compile-flags>-args summary -endargs</compile-flags>
+    </default>
+  </test>
 </regress-exe>

+ 47 - 0
test/Date/toStringAndToUTCStringYearPadding.js

@@ -0,0 +1,47 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+// For dates whose years are less than 1000, Date.toString() and Date.toUTCString() should pad the years
+// to 4 digits.
+// See https://github.com/Microsoft/ChakraCore/pull/4067
+
+/// <reference path="../UnitTestFramework/UnitTestFramework.js" />
+if (this.WScript && this.WScript.LoadScriptFile) { // Check for running in ch
+    this.WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js");
+}
+
+function testDate(DateObj, toStringExpected, toUTCStringExpected) {
+    assert.areEqual(toStringExpected, DateObj.toString(), "Date.toString() returns invalid value.");
+    assert.areEqual(toUTCStringExpected, DateObj.toUTCString(), "Date.toUTCString() returns invalid value.");
+}
+
+let tests = [{
+    name: "test if Date.toString() and Date.toUTCString() pad positive years to four digits",
+    body: function () {
+        testDate(new Date("0001-10-13T05:16:33Z"), "Fri Oct 12 0001 22:16:33 GMT-0700 (Pacific Daylight Time)",
+            "Sat, 13 Oct 0001 05:16:33 GMT");
+        testDate(new Date("0011-10-13T05:16:33Z"), "Wed Oct 12 0011 22:16:33 GMT-0700 (Pacific Daylight Time)",
+            "Thu, 13 Oct 0011 05:16:33 GMT");
+        testDate(new Date("0111-10-13T05:16:33Z"), "Mon Oct 12 0111 22:16:33 GMT-0700 (Pacific Daylight Time)",
+            "Tue, 13 Oct 0111 05:16:33 GMT");
+        testDate(new Date("1111-10-13T05:16:33Z"), "Thu Oct 12 1111 22:16:33 GMT-0700 (Pacific Daylight Time)",
+            "Fri, 13 Oct 1111 05:16:33 GMT");
+    }
+},
+{
+    name: "test if Date.toString() and Date.toUTCString() pad negative years to four digits",
+    body: function () {
+        testDate(new Date("-000001-10-13T05:16:33Z"), "Tue Oct 12 -0001 22:16:33 GMT-0700 (Pacific Daylight Time)",
+            "Wed, 13 Oct -0001 05:16:33 GMT");
+        testDate(new Date("-000011-10-13T05:16:33Z"), "Thu Oct 12 -0011 22:16:33 GMT-0700 (Pacific Daylight Time)",
+            "Fri, 13 Oct -0011 05:16:33 GMT");
+        testDate(new Date("-000111-10-13T05:16:33Z"), "Sat Oct 12 -0111 22:16:33 GMT-0700 (Pacific Daylight Time)",
+            "Sun, 13 Oct -0111 05:16:33 GMT");
+        testDate(new Date("-001111-10-13T05:16:33Z"), "Wed Oct 12 -1111 22:16:33 GMT-0700 (Pacific Daylight Time)",
+            "Thu, 13 Oct -1111 05:16:33 GMT");
+    }
+}];
+
+testRunner.run(tests, { verbose: WScript.Arguments[0] != "summary" });