Date object. You can have hard time working with it, especially if you want to support time zones. In this post I would like to outline quircks of
In order to create a
Date object, you just do:
var now = new Date();
This will create a date set to now.
If you want to create
Date on specific day:
var year = 2015; var month = 2-1; // February var day = 27; var now = new Date(year, month, day);
Here you encounter the first quirk: months are numbered from 0 to 11. January is 0, December is 11.
You can also specify hours, minutes, seconds, and milliseconds as additional parameters (no more pitfalls here):
var year = 2015; var month = 2-1; // February var day = 27; var hours = 14; // 2PM var minutes = 56; var seconds = 37; var milliseconds = 997; var now = new Date(year, month, day, hours, minutes, seconds, milliseconds);
For more details about creating
Date, check Date at MDN.
If you want to display a date, there are a few available converters. Here are the most commonly used:
var date = new Date(2015, 1, 27, 14, 56, 37, 997); console.log(date.toDateString()); // Fri Feb 27 2015 console.log(date.toTimeString()); // 14:56:37 GMT-0800 (Pacific Standard Time) console.log(date.toLocaleDateString()); // 2/27/2015 console.log(date.toLocaleTimeString()); // 2:56:37 PM console.log(date.toUTCString()); // Fri, 27 Feb 2015 22:56:37 GMT console.log(date.toGMTString()); // Fri, 27 Feb 2015 22:56:37 GMT console.log(date.toISOString()); // 2015-02-27T22:56:37.997Z console.log(date.toJSON()); // 2015-02-27T22:56:37.997Z
Be careful with 3 and 4. Both return different results, depended on user’s machine settings and geographical location. This may cause UI issues (some date formats might be long).
Converters 5 and 6 are equivalent in all, most popular browsers. However
toGMTString is deprecated.
Converters 7 and 8 are also equivalent. Moreover,
toISOString underneath to return result.
There is no significant issues with displaying Date, but there is no way to format it with custom format (e.g., ‘YYYY-MM-DD HH:mm’) like in C# or Java.
Alternative for formatting is Intl.DateTimeFormat object from ECMAScript Internationalization API. However, this API is not yet supported by older browsers, most of mobile browsers, and Safari (check browser compatibility on MDN).
More tricky than displaying dates, is parsing them. There are two common ways to parse date from string:
var parsedDate1 = new Date("2015-02-27 22:56:37"); var parsedDate2 = Date.parse("2015-02-27 22:56:37");
Date object, second – number 1425106597000 (milliseconds since January 1, 1970, 00:00:00 UTC).
There is one, very unpleasant detail in parsing:
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. Therefore Date objects produced using those strings will represent different moments in time 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 (this behavior is changed in ECMAScript ed 6 so that both will be treated as local).Source: MDN
This means that
date2 below (created from machine located in Seattle, WA) are different:
var date1 = new Date("2014-01-02"); var date2 = new Date("1/2/2014"); console.log(date1); // Wed Jan 01 2014 16:00:00 GMT-0800 (Pacific Standard Time) console.log(date2); // Thu Jan 02 2014 00:00:00 GMT-0800 (Pacific Standard Time)
Recommended format for parsing is:
YYYY/MM/DD – user local settings independent. It always assumes local timezone offset for date string given as a parameter.
var date1 = new Date("2014/01/02"); console.log(date1); // Thu Jan 02 2014 00:00:00 GMT-0800 (Pacific Standard Time)
Date does not support time zones, but only timezone offsets. This is a definition of both from Wikipedia:
A time zone is a geographical region where just about everybody observes the same standard time.
A time offset is an amount of time subtracted from or added to UTC to get the current civil time – whether it’s standard time or Daylight saving time.
In other words: time zone is constant (as long as government does not changed it) for some place (e.g., San Francisco) all the time, while time zone offset changes (usually, twice a year – this is what we call ‘daylight savings’).
var myDate = new Date(); var timezoneOffset = myDate.getTimezoneOffset(); // result in minutes
One more pitfall: local timezone offset is always set depends on value of
Date object. Thus, for Computer located in Seattle, WA:
var date1 = new Date(2015,1,20); // date in Pacific Standard Time (before timezone offset change) var date2 = new Date(2015,2,20); // date in Pacific Daylight Time (after timezone offset change) console.log(date1.getTimezoneOffset()); // 480 console.log(date2.getTimezoneOffset()); // 420
In this case your current ‘local’ timezone offset (for the time in which you are creating Date object) does not matter.
Even if you create Date object with date before the time change, and then you modify it to date after the time change – its timezone offset changes to reflect offset for the new (current) value:
var date = new Date(2015,1,20); // date in Pacific Standard Time console.log(date.getTimezoneOffset()); // 480 date.setMonth(2); // change month so date is in Pacific Daylight Time now console.log(date.getTimezoneOffset()); // 420
Moment Timezone – a library built on top of Moment.js – supports real time zones (not only timezone offsets). The data for Moment Timezone comes from the IANA Time Zone Database – most popular time zone database. New versions are released periodically as timezone laws change in various countries.
Consider using Moment.js and Moment Timezone in your application when you are doing more complex operations with dates. Especially when you want to support time zones.
To get a quick insight why dealing with time zones is very complex, check this video.