Date objects in JavaScript — the tricky parts

Let's assume it's 30 September 2020. It may seem counter-intuitive, but the current date plays a big role when creating Date objects in JavaScript.

Here's the first part of the problem.

let date = new Date();

date.setYear(2020); // 2020
date.setDate(31); // 31
date.setMonth(7); // August

// Result: Sat Aug 01 2020 14:26:55 GMT+0200

Side note: When using the setMonth method it's important to remember months are indexed starting from 0. January is at position 0, December is at position 11.

Now that's a very strange result.

The resulting Date object's day of the month is 01.

Before we start pulling the hair out let's break it down and consider what's going on here. We're creating a Date object first, then setting the year, then the month and finally the day of the month. At the time of setting the date to 31 it's assumed we're in September (based on the current date). Since September 2020 only has 30 days, the day of the month gets "autocorrected" to 01.

This "autocorrecting" feature seems like a good idea, but ends up causing more problems than it solves. We have to be aware of the way things work in JavaScript land.

You might be tempted to switch the order of the calls and call setMonth first, followed by setDate. This partly solves the issue, at least when we consider the example above.

Being smarter now let's try to create a different Date object and set the date to 15 February 2020.

let date = new Date();

date.setYear(2020); // 2020
date.setMonth(1); // February
date.setDate(15); // 15

// Result: Sun Mar 15 2020 14:13:14 GMT+0100

Weird. Why is it a date in March even though we switched the order of the calls and called setMonth first? It's a similar problem at play...

At the time of calling setMonth it's assumed the day of the month is 30 (based on the current date again). Since February 2020 only has 29 days the month gets "autocorrected" to March.

I think this proves switching the order of the calls didn't really solve the problem.

What's the solution?

let date = new Date(2020, 7, 31);
// Result: Mon Aug 31 2020 00:00:00 GMT+0200

date = new Date(2020, 1, 15);
// Result: Sat Feb 15 2020 00:00:00 GMT+0100

Pass the year/month/day of the month to the Date constructor.