Things I learned about JavaScript’s Date

JavaScript’s Date does not stop to amaze me.
Probably every developer has encountered lots of problems when working with it.
Most projects use other date libraries like Moment.js or JS-Joda to cope with its shortcomings.
In case you want to or have to stick to JavaScript’s Date here are some things I find useful to remember.

Time-Zones

The most important thing of all is that you can’t determine the time-zone of a Date-object by simply looking at it.

You can only retrieve information related to the browser’s local time-zone or to the UTC-time-zone.
Date provides various getters to do that:

  • getUTCHours / getHours
  • getUTCMinutes / getMinutes
  • getUTCSeconds / getSeconds

The result of the UTC-getters will be the same all over the world whereas the result of the non-UTC-getters depends on the browser’s local time-zone.

Hence if you want to compare dates compare them using the UTC-time zone. This can be achieved by using the toISOString-function.

If you want to compare dates always use toISOString!

Date-constructors

You need to take extra care when creating Date-objects. Date provides several constructor-signatures:

ConstructortoStringtoISOStringgetHoursgetUTCHoursis a UTC date
new Date(1692967999168)Fri Aug 25 2023 14:53:19 GMT+0200 (Central European Summer Time)2023-08-25T12:53:19.168Z1412yes
new Date(‚2023-08-25T12:53:19.168Z‘)Fri Aug 25 2023 14:53:19 GMT+0200 (Central European Summer Time)2023-08-25T12:53:19.168Z1412yes
new Date(‚2023-08-25 12:53:19.168 UTC‘)Fri Aug 25 2023 14:53:19 GMT+0200 (Central European Summer Time)2023-08-25T12:53:19.168Z1412yes
new Date(2023, 7, 25, 12, 53, 19, 168)Fri Aug 25 2023 12:53:19 GMT+0200 (Central European Summer Time)2023-08-25T10:53:19.168Z1210no

As you can see there are constructors that interpret their arguments as a UTC date and constructors that interpret their arguments as a local date.

I recommend to use the constructors that interpret their arguments as a UTC date. Combined with the UTC-getters you can avoid the conversion to the browser’s local time-zone altogether.

Stick to UTC-dates as far as possible!

Formatting Dates

Most of the time human beings want to view the date in their time-zone (which is probably not UTC).

In that case try not to convert the Date-object programmatically but use the Intl.DateTimeFormat to format the date:

console.log(
  new Intl.DateTimeFormat('en-GB', { dateStyle: 'full', timeStyle: 'long', timeZone: 'Australia/Sydney' }).format(new Date(1692967999168)),
);
// result: Friday, 25 August 2023 at 22:53:19 GMT+10Code-Sprache: JavaScript (javascript)

Use Intl.DateTimeFormat to format a date with a certain time-zone.

Invalid Dates

Sometimes you may encounter invalid Date-objects. That may happen on purpose or by accident (e.g. an invalid user input).

An invalid Date-object is still an object of type Date but you may run into errors if you try to do something useful with it:

new Date('13-13-13').toISOString();
// will throw: Uncaught RangeError: Invalid time value at Date.toISOStringCode-Sprache: JavaScript (javascript)

Fortunately, there is an easy way to detect an invalid date. Calling getTime on an invalid date will return NaN (not a number):

const invalidDate = new Date('13-13-13');
const timestamp = invalidDate.getTime();
Number.isNaN(timestamp); // evaluates to true!Code-Sprache: JavaScript (javascript)

getTime will evaluate to Number.NaN if the date is invalid.

This implies that you can create an invalid date with new Date(Number.NaN).

Conclusion

It’s hard to work with JavaScript-Date objects. Try to stick to UTC dates and use other time-zones only when formatting the date.

I hope you can use some of the provided insights.

Let me know if you find a bug or want something to be added.

Until then, happy coding!