I input new Date("2017-01-01")
in chrome console, the output shows its hour is 8, but new Date("2017-01-1")
and new Date("2017-1-01")
shows their hour are both 0, so how does new Date(dateString)
parse?
new Date("2017-01-01")
// Sun Jan 01 2017 08:00:00 GMT+0800 (中国标准时间)*
new Date("2017-01-1")
// Sun Jan 01 2017 00:00:00 GMT+0800 (中国标准时间)*
new Date("2017-1-1")
// Sun Jan 01 2017 00:00:00 GMT+0800 (中国标准时间)*
new Date("2017-1-01")
// Sun Jan 01 2017 00:00:00 GMT+0800 (中国标准时间)*
new Date creates a new Date object that you can modify or initialize with a different date while Date returns a string of the current date/time, ignoring its arguments.
Date() returns an implementation dependent string representing the current date and time. new Date() returns a Date object that represents the current date and time. ;-) Yeah, I know.
The T separates the date portion from the time-of-day portion. The Z on the end means UTC (that is, an offset-from-UTC of zero hours-minutes-seconds). The Z is pronounced “Zulu”.
"The expression new Date() returns the current time in internal format, as an object containing the number of milliseconds elapsed since the start of 1970 in UTC.
"2017-01-01" follows the ISO standard ES5 Date Time String format (simplification of ISO 8601 Extended Format), and therefore it is in UTC time, which is 8am in China. All other strings are parsed as local time in Chrome1.
1 Relevant source code in Chromium: https://cs.chromium.org/chromium/src/v8/src/dateparser-inl.h?type=cs&l=16
Date parsing in Chromium follows the standard ES5 rules as well as these extra rules:
:
is a time value, and is added to the TimeComposer
. A number followed by ::
adds a second zero as well. A number followed by .
is also a time and must be followed by milliseconds. Any other number is a date component and is added to DayComposer
.Day
composer.(+|-)(hhmm|hh:)
.+
or -
) or unmatched )
after a number has been read (before the first number, any garbage is allowed)."1970-01-01"
will be in UTC time-zone not in local time-zone.First note that "2017-01-01" is parsed in UTC time because it is a "date" string instead of a "date-time" string, and it matches the ES5 definition of a "date" string. If time is attached, then it will follow the ISO standard and parse it in local time.
Examples:
2017-01-01
- Jan 1, 2017 in UTC time2017-01-01T00:00
- Jan 1, 2017 in local time2017-1-1
- Jan 1, 2017 in local time2017-(hello)01-01
- Jan 1, 2017 in local timemay 2017-01-01
- May 1, 2017 in local timemayoooo 2017-01-01
- May 1, 2017 in local time"jan2017feb-mar01apr-may01jun"
- Jun 1, 2017 in local timedifference between new Date("2017-01-01") and new Date("2017-1-1")
new Date("2017-01-01")
is in-spec (more below). new Date("2017-1-1")
is not, and so falls back on any "...implementation-specific heuristics or implementation-specific date formats" the JavaScript engine wants to apply. E.g., you have no guarantee how (or whether) it will successfully parse and if so, whether it will be parsed as UTC or local time.
Although new Date("2017-01-01")
is in-spec, sadly what browsers are supposed to do with it has been a moving target, because it doesn't have a timezone indicator on it:
new Date("2017-01-01")
is parsed in UTC.new Date("2017-01-01")
is parsed as local time.-
in them as UTC for years. So as of ES2016, date-only forms (like "2017-01-01"
) are parsed in UTC, but date/time forms (like "2017-01-01T00:00:00"
) are parsed in local time.Sadly, not all JavaScript engines currently implement the spec. Chrome (as of this writing, v56) parses date/time forms in UTC even though they should be local time (so does IE9). But Chrome, Firefox, and IE11 (I don't have IE10 or Edge handy) all handle date-only forms correctly (as UTC). IE8 doesn't implement the ISO-8601 form at all (having been released before the ES5 spec was released).
When parsing dates, JavaScript interprets ISO dates as UTC time and other formats as local time.
As MDN article suggests,
Where the string is ISO 8601 date only, the UTC time zone is used to interpret arguments.
Given a date string of "March 7, 2014", parse() assumes a local time zone, but given an ISO format such as "2014-03-07" it will assume a time zone of UTC (ES5 and ECMAScript 2015). Therefore Date objects produced using those strings may represent different moments in time depending on the version of ECMAScript supported unless the system is set with a local time zone of UTC. This means that two date strings that appear equivalent may result in two different values depending on the format of the string that is being converted.
// 2017-03-28 is interpreted as UTC time,
// shown as 2017-03-28 00:00:00 in UTC timezone,
// shown as 2017-03-28 06:00:00 in my timezone:
console.log("ISO dates:");
var isoDates = [new Date("2017-03-28")];
for (var dt of isoDates)
{
console.log(dt.toUTCString() + " / " + dt.toLocaleString());
}
// Other formats are interpreted as local time,
// shown as 2017-03-27 18:00:00 in my timezone,
// shown 2017-03-28 00:00:00 in my timezone:
console.log("Other formats:");
var otherDates = [new Date("2017-3-28"), new Date("March 28, 2017"), new Date("2017/03/28")];
for (var dt of otherDates)
{
console.log(dt.toUTCString() + " / " + dt.toLocaleString());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With