Thursday, February 22, 2018

The interface to JavaScript's Date object is kinda broken

Here's an amusing thing to type into your favorite JavaScript console:

new Date('2018-01-01').getFullYear()

The response I get is 2017, which is surprising, at best.

What's happening?

The first part of the problem is that the Date object is actually a date and time object, and so new Date('2018-01-01') creates an object that has the date and time of January 1st, 2018 00:00 GMT. Which in and of itself is a reasonable enough choice.

The part that leads to the surprising result is that .getFullYear() returns a localized result, and since I am in a GMT+7 time zone, January 1st, 2018 00:00 GMT is actually December 31st, 2017 17:00 local time, and so .getFullYear() tells me it's still 2017.

Of course, the Date interface is broken in other ways too (.getYear() is actually non-Y2K compliant, in spite of the fact that it was presumably first designed and implemented less than a decade prior to the year 2000).

Can anything be done?

It turns out that dealing with time and time zones is actually surprisingly complex, and given JavaScript's "colorful" history, it's not surprising that the Date interface has its share of quirks. Really, I just wish there as an object for dealing with dates alone, without an accompanying time. Date would be a fine name for that object, if it weren't already taken.

I'm in a situation where I want to be able to deal with dates in JavaScript, and it seems like my choices are either to use the Date object with its rather non-intuitive interface, or roll my own date-only object. Neither choice seems optimal, but I think rolling my own date-only object would add more inertia to my projects than I'm willing to take on right now.