JavaScript Date has too many traps

JavaScript Date has too many traps.

I was dealing with dates and times with JavaScript and I caught a trap from one to the next, so write it down for those who come later.

##Date.parse returns an integer rather than a Date

Date.parse returns milliseconds from 00:00:00 on January 1, 1970 at the World Pact agreement. To get a Date, pass it to new Date. Even if you pass string directly to new Date, it is the same behavior, so this is concise.

msec = Date.parse("Thu, 06 Sep 2012 00:00:00 +0900"); // 1346857200000
date = new Date(msec); // Date
date = new Date("Thu, 06 Sep 2012 00:00:00 +0900"); // Date

##Do not use getYear to get the year

Date.prototype.getYear is deprecated in years since 1900. Use Date.prototype.getFullYear.

date = new Date("Thu, 06 Sep 2012 00:00:00 +0900")
date.getYear(); // 112 (2012 - 1900)
date.getFullYear(); // 2012

##Month starts from 0

Even with the second argument of the new Date, Date.prototype.getMonth, the month is represented by 0 - 11.

new Date(2012, 8, 6); // Thu, Sep 06 2012 00:00:00 GMT+0900 (JST)
new Date("Thu, 06 Sep 2012 00:00:00 +0900").getMonth();  // 8

##It is not getDay to get the day

Date.prototype.getDay returns the day of the week with 0 as Sunday. Date is Date.prototype.getDate. Unlike the moon this is 1-31.

date = new Date("Thu, 06 Sep 2012 00:00:00 +0900");
date.getDay(); // 4 (Thursday)
date.getDate(); // 6 (6th)

##The sign of getTimezoneOffset is opposite to ordinary notation

Date.prototype.getTimezoneOffset returns the time difference from UTC in minutes, but the sign is opposite from the character string representation that usually indicates the time zone.

date = new Date("Thu, 06 Sep 2012 00:00:00 +0900");
date.getTimezoneOffset(); // -540 (540 minutes = +0900 in 9 hours)

##Use getTime when comparing

Even when Date shows the same date and time, == and === will be false if the objects are different.

s = "Thu, 06 Sep 2012 00:00:00 +0900"
new Date(s) == new Date(s) // false
new Date(s) === new Date(s) // false

Since Date.prototype.getTime gets elapsed milliseconds since 00:00:00 on January 1, 1970 at World Pact agreement this is compared.

s = "Thu, 06 Sep 2012 00:00:00 +0900"
new Date(s).getTime() // 1346857200000
new Date(s).getTime() == new Date(s).getTime() // true
new Date(s).getTime() === new Date(s).getTime() // true

By the way, even with comparison between Date will work as expected, but we do not recommend it because it is confusing.

(There is also a way to compare by subtracting it or casting it to a number using the unary operator +, but there is no reason to use it because the intention is difficult to understand and it is slow)

##Get a string representation with toISOString or toJSON

Methods for obtaining character string representation defined in ECMAScript 3 are as follows (in parentheses, EMCAScript 3 specification (PDF) item number).

toString (15.9.5.2) toDateString (15.9.5.3) toTimeString (15.9.5.4) toLocaleString (15.9.5.5) toLocaleDateString (15.9.5.6) toLocaleTimeString (15.9.5.7) Both are written as "The contents of the string are implementation - dependent", the format is implementation - dependent.

When I tried it, only IE was different, but do not blame it because there is no standard.

date = new Date("Thu, 06 Sep 2012 00:00:00 +0900");
date.toString() // Chrome21:  "Thu Sep 06 2012 00:00:00 GMT+0900 (JST)"
date.toString() // Firefox14: "Thu Sep 06 2012 00:00:00 GMT+0900 (JST)"
date.toString() // Safari:    "Thu Sep 06 2012 00:00:00 GMT+0900 (JST)"
date.toString() // IE8:       "Thu Sep 6 00:00:00 UTC+0900 2012"

In ECMAScript 5, the character string representation is defined as a subset of ISO 8601 and it is obtained by toISOString.

date = new Date("Thu, 06 Sep 2012 00:00:00 +0900");
date.toISOString(); // "2012-09-05T15:00:00.000Z"

Since toJSON called from JSON.stringify also uses toISOString, it also becomes ISO 8601 when JSON.stringify is done.

date = new Date("Thu, 06 Sep 2012 00:00:00 +0900");
JSON.stringify(date); // ""2012-09-05T15:00:00.000Z""

Also, Date.parse and new Date also specify that you can parse ISO 8601 (a subset).

new Date("2012-09-05T15:00:00.000Z") // Thu Sep 06 2012 00:00:00 GMT+0900 (JST)

##The date may change when it is set to JSON

As mentioned above, the string representation when JSON.stringify is done is ISO 8601, but it always becomes UTC by ignoring the time zone.

As a result, the date changes depending on the time zone and time.

// Japan time 6 o'clock 0 UTC 5 th 5 o'clock in the UTC
date = new Date("2012-09-06T00:00:00+0900");
JSON.stringify(date) // "2012-09-05T15:00:00.000Z"

It is possible to avoid date by changing the Date.prototype.toJSON by yourself and returning a character string including the time zone, but since it is out of the standard, it is safer to make it a character string before JSON.stringify.

##Time does not match when parsing dates and when specifying numbers

If you parse a date string that does not include a time in new Date or Date.parse, it will be UTC 00: 00: 00.

// UTC 0 o'clock = JST 9 o'clock
new Date ("2014-11-10") // Mon Nov 10 2014 09: 00: 00 GMT + 0900 (JST)

On the other hand, when new date (2014, 10, 10), etc. is set as local time, it becomes 00:00:00 in local time, and the time does not match with this.

new Date(2014, 10, 10) // Mon Nov 10 2014 00:00:00 GMT+0900 (JST)

The behavior of the former is based on the ECMAScript 5 specification that it treats it as UTC when there is no time zone character string in the date string.

The value of an absent time zone offset is "Z". 15.9.1.15 Date Time String Format

However, in ECMAScript 6 draft (October 14, 2014), there is a description that it will be in local time.

If the time zone offset is absent, the date-time is interpreted as a local time. 20.3.1.15 Date Time String Format

##ISO 8601 can not be parsed in IE 8

Since the format that Date.parse can parse is not specified in ECMAScript 3, it is implementation-dependent.

If you try it, OK for RFC 2822 in major browsers, not for ISO 8601 for IE 8 (IE 9 OK).

Date.parse("2012-01-01 00:00:00"); // With IE 8 NaN

As stated above, ECMAScript 5 stipulates that you can parse ISO 8601 (a subset).

Delete an article

Deleted articles are gone forever. Are you sure?