Commit d31c5410 authored by littledan's avatar littledan Committed by Commit bot

[builtins] Apply ES2016 conditional default timezone semantics

ES2016 changed the default timezone of dates to be conditional on
whether a time is included. The semantics were a compromise approach
based on web compatibility feedback from V8, but until now, we have been
shipping ES5.1 default timezone semantics. This patch implements the
new semantics, following ChakraCore and SpiderMonkey (though JSC
implements V8's previous semantics).

BUG=chromium:589858

Review-Url: https://codereview.chromium.org/2648603002
Cr-Commit-Position: refs/heads/master@{#43239}
parent d21621cf
...@@ -343,8 +343,13 @@ DateParser::DateToken DateParser::ParseES5DateTime( ...@@ -343,8 +343,13 @@ DateParser::DateToken DateParser::ParseES5DateTime(
} }
if (!scanner->Peek().IsEndOfInput()) return DateToken::Invalid(); if (!scanner->Peek().IsEndOfInput()) return DateToken::Invalid();
} }
// Successfully parsed ES5 Date Time String. Default to UTC if no TZ given. // Successfully parsed ES5 Date Time String.
if (tz->IsEmpty()) tz->Set(0); // ES#sec-date-time-string-format Date Time String Format
// "When the time zone offset is absent, date-only forms are interpreted
// as a UTC time and date-time forms are interpreted as a local time."
if (tz->IsEmpty() && time->IsEmpty()) {
tz->Set(0);
}
day->set_iso_date(); day->set_iso_date();
return DateToken::EndOfInput(); return DateToken::EndOfInput();
} }
......
...@@ -245,9 +245,9 @@ var testCasesES5Misc = [ ...@@ -245,9 +245,9 @@ var testCasesES5Misc = [
['2000-01T08:00:00.099Z', 946713600099], ['2000-01T08:00:00.099Z', 946713600099],
['2000-01T08:00:00.999Z', 946713600999], ['2000-01T08:00:00.999Z', 946713600999],
['2000-01T00:00:00.001-08:00', 946713600001], ['2000-01T00:00:00.001-08:00', 946713600001],
['2000-01-01T24:00', 946771200000], ['2000-01-01T24:00Z', 946771200000],
['2000-01-01T24:00:00', 946771200000], ['2000-01-01T24:00:00Z', 946771200000],
['2000-01-01T24:00:00.000', 946771200000], ['2000-01-01T24:00:00.000Z', 946771200000],
['2000-01-01T24:00:00.000Z', 946771200000]]; ['2000-01-01T24:00:00.000Z', 946771200000]];
var testCasesES5MiscNegative = [ var testCasesES5MiscNegative = [
...@@ -261,6 +261,31 @@ var testCasesES5MiscNegative = [ ...@@ -261,6 +261,31 @@ var testCasesES5MiscNegative = [
'2000-01-01T24:00:00.001', '2000-01-01T24:00:00.001',
'2000-01-01T24:00:00.999Z']; '2000-01-01T24:00:00.999Z'];
// TODO(littledan): This is an hack that could break in historically
// changing timezones that happened on this day, but allows us to
// check the date value for local times.
var localOffset = new Date('2000-01-01').getTimezoneOffset()*1000*60;
// Sanity check which is even more of a hack: in the timezones where
// these tests are likely to be run, the offset is nonzero because
// dates which don't include Z are in the local timezone.
if (this.Intl &&
["America/Los_Angeles", "Europe/Berlin", "Europe/Madrid"].indexOf(
Intl.DateTimeFormat().resolvedOptions().timeZone) != -1) {
assertTrue(localOffset != 0);
}
var testCasesES2016TZ = [
// If the timezone is absent and time is present, use local time
['2000-01-02T00:00', 946771200000 + localOffset],
['2000-01-02T00:00:00', 946771200000 + localOffset],
['2000-01-02T00:00:00.000', 946771200000 + localOffset],
// If timezone is absent and time is absent, use UTC
['2000-01-02', 946771200000],
['2000-01-02', 946771200000],
['2000-01-02', 946771200000],
];
// Run all the tests. // Run all the tests.
testCasesUT.forEach(testDateParse); testCasesUT.forEach(testDateParse);
...@@ -282,6 +307,7 @@ testCasesES5MiscNegative.forEach(function (s) { ...@@ -282,6 +307,7 @@ testCasesES5MiscNegative.forEach(function (s) {
assertTrue(isNaN(Date.parse(s)), s + " is not NaN."); assertTrue(isNaN(Date.parse(s)), s + " is not NaN.");
}); });
testCasesES2016TZ.forEach(testDateParseMisc);
// Test that we can parse our own date format. // Test that we can parse our own date format.
// (Dates from 1970 to ~2070 with 150h steps.) // (Dates from 1970 to ~2070 with 150h steps.)
......
...@@ -193,110 +193,112 @@ assertEquals(-8640000000000000, Date.UTC(1970, 0, 1 - 100000001, 24)); ...@@ -193,110 +193,112 @@ assertEquals(-8640000000000000, Date.UTC(1970, 0, 1 - 100000001, 24));
// Parsing ES5 ISO-8601 dates. // Parsing ES5 ISO-8601 dates.
// When TZ is omitted, it defaults to 'Z' meaning UTC. // When TZ is omitted, it defaults to the local timezone if there is
// no time, and to UTC if a time is provided. This file tests the
// "timezone present" case; timezone absent is tested by test/mjsunit/date-parse.js
// Check epoch. // Check epoch.
assertEquals(0, Date.parse("1970-01-01T00:00:00.000+00:00")); assertEquals(0, Date.parse("1970-01-01T00:00:00.000+00:00"));
assertEquals(0, Date.parse("1970-01-01T00:00:00.000-00:00")); assertEquals(0, Date.parse("1970-01-01T00:00:00.000-00:00"));
assertEquals(0, Date.parse("1970-01-01T00:00:00.000Z")); assertEquals(0, Date.parse("1970-01-01T00:00:00.000Z"));
assertEquals(0, Date.parse("1970-01-01T00:00:00.000")); assertEquals(0, Date.parse("1970-01-01T00:00:00.000Z"));
assertEquals(0, Date.parse("1970-01-01T00:00:00")); assertEquals(0, Date.parse("1970-01-01T00:00:00Z"));
assertEquals(0, Date.parse("1970-01-01T00:00")); assertEquals(0, Date.parse("1970-01-01T00:00Z"));
assertEquals(0, Date.parse("1970-01-01")); assertEquals(0, Date.parse("1970-01-01Z"));
assertEquals(0, Date.parse("1970-01T00:00:00.000+00:00")); assertEquals(0, Date.parse("1970-01T00:00:00.000+00:00"));
assertEquals(0, Date.parse("1970-01T00:00:00.000-00:00")); assertEquals(0, Date.parse("1970-01T00:00:00.000-00:00"));
assertEquals(0, Date.parse("1970-01T00:00:00.000Z")); assertEquals(0, Date.parse("1970-01T00:00:00.000Z"));
assertEquals(0, Date.parse("1970-01T00:00:00.000")); assertEquals(0, Date.parse("1970-01T00:00:00.000Z"));
assertEquals(0, Date.parse("1970-01T00:00:00")); assertEquals(0, Date.parse("1970-01T00:00:00Z"));
assertEquals(0, Date.parse("1970-01T00:00")); assertEquals(0, Date.parse("1970-01T00:00Z"));
assertEquals(0, Date.parse("1970-01")); assertEquals(0, Date.parse("1970-01Z"));
assertEquals(0, Date.parse("1970T00:00:00.000+00:00")); assertEquals(0, Date.parse("1970T00:00:00.000+00:00"));
assertEquals(0, Date.parse("1970T00:00:00.000-00:00")); assertEquals(0, Date.parse("1970T00:00:00.000-00:00"));
assertEquals(0, Date.parse("1970T00:00:00.000Z")); assertEquals(0, Date.parse("1970T00:00:00.000Z"));
assertEquals(0, Date.parse("1970T00:00:00.000")); assertEquals(0, Date.parse("1970T00:00:00.000Z"));
assertEquals(0, Date.parse("1970T00:00:00")); assertEquals(0, Date.parse("1970T00:00:00Z"));
assertEquals(0, Date.parse("1970T00:00")); assertEquals(0, Date.parse("1970T00:00Z"));
assertEquals(0, Date.parse("1970")); assertEquals(0, Date.parse("1970Z"));
assertEquals(0, Date.parse("+001970-01-01T00:00:00.000+00:00")); assertEquals(0, Date.parse("+001970-01-01T00:00:00.000+00:00"));
assertEquals(0, Date.parse("+001970-01-01T00:00:00.000-00:00")); assertEquals(0, Date.parse("+001970-01-01T00:00:00.000-00:00"));
assertEquals(0, Date.parse("+001970-01-01T00:00:00.000Z")); assertEquals(0, Date.parse("+001970-01-01T00:00:00.000Z"));
assertEquals(0, Date.parse("+001970-01-01T00:00:00.000")); assertEquals(0, Date.parse("+001970-01-01T00:00:00.000Z"));
assertEquals(0, Date.parse("+001970-01-01T00:00:00")); assertEquals(0, Date.parse("+001970-01-01T00:00:00Z"));
assertEquals(0, Date.parse("+001970-01-01T00:00")); assertEquals(0, Date.parse("+001970-01-01T00:00Z"));
assertEquals(0, Date.parse("+001970-01-01")); assertEquals(0, Date.parse("+001970-01-01Z"));
assertEquals(0, Date.parse("+001970-01T00:00:00.000+00:00")); assertEquals(0, Date.parse("+001970-01T00:00:00.000+00:00"));
assertEquals(0, Date.parse("+001970-01T00:00:00.000-00:00")); assertEquals(0, Date.parse("+001970-01T00:00:00.000-00:00"));
assertEquals(0, Date.parse("+001970-01T00:00:00.000Z")); assertEquals(0, Date.parse("+001970-01T00:00:00.000Z"));
assertEquals(0, Date.parse("+001970-01T00:00:00.000")); assertEquals(0, Date.parse("+001970-01T00:00:00.000Z"));
assertEquals(0, Date.parse("+001970-01T00:00:00")); assertEquals(0, Date.parse("+001970-01T00:00:00Z"));
assertEquals(0, Date.parse("+001970-01T00:00")); assertEquals(0, Date.parse("+001970-01T00:00Z"));
assertEquals(0, Date.parse("+001970-01")); assertEquals(0, Date.parse("+001970-01Z"));
assertEquals(0, Date.parse("+001970T00:00:00.000+00:00")); assertEquals(0, Date.parse("+001970T00:00:00.000+00:00"));
assertEquals(0, Date.parse("+001970T00:00:00.000-00:00")); assertEquals(0, Date.parse("+001970T00:00:00.000-00:00"));
assertEquals(0, Date.parse("+001970T00:00:00.000Z")); assertEquals(0, Date.parse("+001970T00:00:00.000Z"));
assertEquals(0, Date.parse("+001970T00:00:00.000")); assertEquals(0, Date.parse("+001970T00:00:00.000Z"));
assertEquals(0, Date.parse("+001970T00:00:00")); assertEquals(0, Date.parse("+001970T00:00:00Z"));
assertEquals(0, Date.parse("+001970T00:00")); assertEquals(0, Date.parse("+001970T00:00Z"));
assertEquals(0, Date.parse("+001970")); assertEquals(0, Date.parse("+001970Z"));
// Check random date. // Check random date.
assertEquals(70671003500, Date.parse("1972-03-28T23:50:03.500+01:00")); assertEquals(70671003500, Date.parse("1972-03-28T23:50:03.500+01:00"));
assertEquals(70674603500, Date.parse("1972-03-28T23:50:03.500Z")); assertEquals(70674603500, Date.parse("1972-03-28T23:50:03.500Z"));
assertEquals(70674603500, Date.parse("1972-03-28T23:50:03.500")); assertEquals(70674603500, Date.parse("1972-03-28T23:50:03.500Z"));
assertEquals(70674603000, Date.parse("1972-03-28T23:50:03")); assertEquals(70674603000, Date.parse("1972-03-28T23:50:03Z"));
assertEquals(70674600000, Date.parse("1972-03-28T23:50")); assertEquals(70674600000, Date.parse("1972-03-28T23:50Z"));
assertEquals(70588800000, Date.parse("1972-03-28")); assertEquals(70588800000, Date.parse("1972-03-28Z"));
assertEquals(68338203500, Date.parse("1972-03T23:50:03.500+01:00")); assertEquals(68338203500, Date.parse("1972-03T23:50:03.500+01:00"));
assertEquals(68341803500, Date.parse("1972-03T23:50:03.500Z")); assertEquals(68341803500, Date.parse("1972-03T23:50:03.500Z"));
assertEquals(68341803500, Date.parse("1972-03T23:50:03.500")); assertEquals(68341803500, Date.parse("1972-03T23:50:03.500Z"));
assertEquals(68341803000, Date.parse("1972-03T23:50:03")); assertEquals(68341803000, Date.parse("1972-03T23:50:03Z"));
assertEquals(68341800000, Date.parse("1972-03T23:50")); assertEquals(68341800000, Date.parse("1972-03T23:50Z"));
assertEquals(68256000000, Date.parse("1972-03")); assertEquals(68256000000, Date.parse("1972-03Z"));
assertEquals(63154203500, Date.parse("1972T23:50:03.500+01:00")); assertEquals(63154203500, Date.parse("1972T23:50:03.500+01:00"));
assertEquals(63157803500, Date.parse("1972T23:50:03.500Z")); assertEquals(63157803500, Date.parse("1972T23:50:03.500Z"));
assertEquals(63157803500, Date.parse("1972T23:50:03.500")); assertEquals(63157803500, Date.parse("1972T23:50:03.500Z"));
assertEquals(63157803000, Date.parse("1972T23:50:03")); assertEquals(63157803000, Date.parse("1972T23:50:03Z"));
assertEquals(63072000000, Date.parse("1972")); assertEquals(63072000000, Date.parse("1972Z"));
assertEquals(70671003500, Date.parse("+001972-03-28T23:50:03.500+01:00")); assertEquals(70671003500, Date.parse("+001972-03-28T23:50:03.500+01:00"));
assertEquals(70674603500, Date.parse("+001972-03-28T23:50:03.500Z")); assertEquals(70674603500, Date.parse("+001972-03-28T23:50:03.500Z"));
assertEquals(70674603500, Date.parse("+001972-03-28T23:50:03.500")); assertEquals(70674603500, Date.parse("+001972-03-28T23:50:03.500Z"));
assertEquals(70674603000, Date.parse("+001972-03-28T23:50:03")); assertEquals(70674603000, Date.parse("+001972-03-28T23:50:03Z"));
assertEquals(70674600000, Date.parse("+001972-03-28T23:50")); assertEquals(70674600000, Date.parse("+001972-03-28T23:50Z"));
assertEquals(70588800000, Date.parse("+001972-03-28")); assertEquals(70588800000, Date.parse("+001972-03-28Z"));
assertEquals(68338203500, Date.parse("+001972-03T23:50:03.500+01:00")); assertEquals(68338203500, Date.parse("+001972-03T23:50:03.500+01:00"));
assertEquals(68341803500, Date.parse("+001972-03T23:50:03.500Z")); assertEquals(68341803500, Date.parse("+001972-03T23:50:03.500Z"));
assertEquals(68341803500, Date.parse("+001972-03T23:50:03.500")); assertEquals(68341803500, Date.parse("+001972-03T23:50:03.500Z"));
assertEquals(68341803000, Date.parse("+001972-03T23:50:03")); assertEquals(68341803000, Date.parse("+001972-03T23:50:03Z"));
assertEquals(68341800000, Date.parse("+001972-03T23:50")); assertEquals(68341800000, Date.parse("+001972-03T23:50Z"));
assertEquals(68256000000, Date.parse("+001972-03")); assertEquals(68256000000, Date.parse("+001972-03Z"));
assertEquals(63154203500, Date.parse("+001972T23:50:03.500+01:00")); assertEquals(63154203500, Date.parse("+001972T23:50:03.500+01:00"));
assertEquals(63157803500, Date.parse("+001972T23:50:03.500Z")); assertEquals(63157803500, Date.parse("+001972T23:50:03.500Z"));
assertEquals(63157803500, Date.parse("+001972T23:50:03.500")); assertEquals(63157803500, Date.parse("+001972T23:50:03.500Z"));
assertEquals(63157803000, Date.parse("+001972T23:50:03")); assertEquals(63157803000, Date.parse("+001972T23:50:03Z"));
assertEquals(63072000000, Date.parse("+001972")); assertEquals(63072000000, Date.parse("+001972Z"));
// Ensure that ISO-years in the range 00-99 aren't translated to the range // Ensure that ISO-years in the range 00-99 aren't translated to the range
// 1950..2049. // 1950..2049.
assertEquals(-60904915200000, Date.parse("0040-01-01")); assertEquals(-60904915200000, Date.parse("0040-01-01T00:00Z"));
assertEquals(-60273763200000, Date.parse("0060-01-01")); assertEquals(-60273763200000, Date.parse("0060-01-01T00:00Z"));
assertEquals(-62167219200000, Date.parse("0000-01-01")); assertEquals(-62167219200000, Date.parse("0000-01-01T00:00Z"));
assertEquals(-62167219200000, Date.parse("+000000-01-01")); assertEquals(-62167219200000, Date.parse("+000000-01-01T00:00Z"));
// Test negative years. // Test negative years.
assertEquals(-63429523200000, Date.parse("-000040-01-01")); assertEquals(-63429523200000, Date.parse("-000040-01-01Z"));
assertEquals(-64060675200000, Date.parse("-000060-01-01")); assertEquals(-64060675200000, Date.parse("-000060-01-01Z"));
assertEquals(-124397510400000, Date.parse("-001972-01-01")); assertEquals(-124397510400000, Date.parse("-001972-01-01Z"));
// Check time-zones. // Check time-zones.
assertEquals(70674603500, Date.parse("1972-03-28T23:50:03.500Z")); assertEquals(70674603500, Date.parse("1972-03-28T23:50:03.500Z"));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment