Duncan's blog

November 17, 2017

JS dates British Summer Time oddness

Filed under: Javascript — duncan @ 7:00 am
Tags: ,

This must be widely documented, but I came across it today and got a bit perplexed by it. I’m sure I must have encountered this in the past, but probably a long while ago.

I was working with some date pickers and comparing the number of months between two dates and getting unexpected results. Say you do this:

date = new Date(2017, 3, 1);

You’d expect it to create a date object for the 1st April. April Fool’s! Instead it seems to create a date for the 31st March, 23:00. Here’s what I get in my browser console:

new Date(2017, 3, 1);
Date 2017-03-31T23:00:00.000Z

If I specify an additional parameter for the hours, and go for 1am, then this gives me the correct date, but with the time set to 00:00, not 01:00:

new Date(2017, 3, 1, 1)
Date 2017-04-01T00:00:00.000Z

Let’s try the same thing with the 2nd April, same problem. It seems to be subtracting 1hr from whatever DateTime I’m creating:

new Date(2017, 3, 2)
Date 2017-04-01T23:00:00.000Z

new Date(2017, 3, 2, 1)
Date 2017-04-02T00:00:00.000Z

Let’s try all the months of the year:

new Date(2017, 0, 1)
Date 2017-01-01T00:00:00.000Z

new Date(2017, 1, 1)
Date 2017-02-01T00:00:00.000Z

new Date(2017, 2, 1)
Date 2017-03-01T00:00:00.000Z

new Date(2017, 3, 1)
Date 2017-03-31T23:00:00.000Z

new Date(2017, 4, 1)
Date 2017-04-30T23:00:00.000Z

new Date(2017, 5, 1)
Date 2017-05-31T23:00:00.000Z

new Date(2017, 6, 1)
Date 2017-06-30T23:00:00.000Z

new Date(2017, 7, 1)
Date 2017-07-31T23:00:00.000Z

new Date(2017, 8, 1)
Date 2017-08-31T23:00:00.000Z

new Date(2017, 9, 1)
Date 2017-09-30T23:00:00.000Z

new Date(2017, 10, 1)
Date 2017-11-01T00:00:00.000Z

new Date(2017, 11, 1)
Date 2017-12-01T00:00:00.000Z

So we can see it’s clearly doing this for any month from April to October, inclusive. i.e. British Summer Time months. It’s not a bug as such, but just added complication to take into account when working with dates.

If we turn the date into a string, it becomes a bit clearer what’s going on, it’s converting the time into British Summer Time, i.e. GMT + 1 (your results may vary depending on your local timezone):

new Date(2017, 3, 1).toString();
"Sat Apr 01 2017 00:00:00 GMT+0100 (GMT Daylight Time)"

More specifically, the BST dates this year start 26th March and end 29th October. If we check those dates at either end of the range, we can see it’s only doing this on the dates just at the edges of that range:

new Date(2017, 2, 25)
Date 2017-03-25T00:00:00.000Z

new Date(2017, 2, 26)
Date 2017-03-26T00:00:00.000Z

new Date(2017, 2, 27)
Date 2017-03-26T23:00:00.000Z


new Date(2017, 9, 28)
Date 2017-10-27T23:00:00.000Z

new Date(2017, 9, 29)
Date 2017-10-28T23:00:00.000Z

new Date(2017, 9, 30)
Date 2017-10-30T00:00:00.000Z

So in other words it’s creating me a time at BST 2017-04-01 00:00:00, but in UTC that’s 2017-03-31 23:00:00. So any Date functions we call on it like getUTCMonth could potentially give us a different value from getMonth:

new Date(2017, 3, 1).getUTCMonth()

new Date(2017, 3, 1).getMonth()

To get around this, you could just add 1 hr to any date you’re creating, either in the constructor, or with the setHours method:

date = new Date(2017, 3, 1);

Taking care that this doesn’t mess up anything else of course.

A better approach would be, instead of just using the Date() constructor, to use it in combination with the Date.UTC() method. This gets us a value in milliseconds without reference to the local timezone.

new Date(Date.UTC(2017, 3, 1))
Date 2017-04-01T00:00:00.000Z

As the MDN documentation states:

“Note: Where Date is called as a constructor with more than one argument, the specifed arguments represent local time. If UTC is desired, use new Date(Date.UTC(…)) with the same arguments.”

Someone I work with seemed to think I’d just got confused by the fact Javascript uses zero-indexed months!


Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: