logoalt Hacker News

tshaddoxyesterday at 5:37 PM6 repliesview on HN

This article lists several of the absurdities of the Date constructor, but only barely touches on the most unforgivable one. The example from the article is:

  // Unless, of course, you separate the year, month, and date with hyphens.
  // Then it gets the _day_ wrong.
  console.log( new Date('2026-01-02') );
  // Result: Date Thu Jan 01 2026 19:00:00 GMT-0500 (Eastern Standard Time)
In this example, the day is "wrong" because the constructor input is being interpreted as midnight UTC on January 2nd, and at that instantaneous point in time, it is 7pm on January 1st in Eastern Standard Time (which is the author's local time zone).

What's actually happening here is a comedy of errors. JavaScript is interpreting that particular string format ("YYYY-MM-DD") as an ISO 8601 date-only form. ISO 8601 specifies that if no time zone designator is provided, the time is assumed to be in local time. The ES5 spec authors intended to match ISO 8601 behavior, but somehow accidentally changed this to 'The value of an absent time zone offset is “Z”' (UTC).

Years later, they had realized their mistakes, and attempted to correct it in ES2015. And you can probably predict what happened. When browsers shipped the correct behavior, they got too many reports about websites which were relying on the previous incorrect behavior. So it got completely rolled back, sacrificed to the altar of "web compatibility."

For more info, see the "Broken Parser" section towards the bottom of this article:

https://maggiepint.com/2017/04/11/fixing-javascript-date-web...


Replies

no_wizardyesterday at 8:52 PM

>So it got completely rolled back, sacrificed to the altar of "web compatibility."

This is why I don't understand the lack of directives.

'use strict'; at the top of a file was ubiquitous for a long time and it worked. It didn't force rolling back incompatibilities, it let you opt into a stricter parsing of JavaScript.

It would have been nice for other wide changes like this to have like a 'strict datetime'; directive which would opt you into using this corrected behavior.

They couldn't and shouldn't do this sort of thing for all changes, but for really major changes to the platform this would be an improvement.

Or they could go all in on internal modules, like how you can import `node:fs` now. They could include corrected versions of globals like

`import Date from 'browser:date';`

has corrected behavior, for example

show 3 replies
OptionOfTyesterday at 6:25 PM

I very much remember coding a function that split the string on their components and then rebuild them to ensure the date was created without time zone.

Sometimes a date is just a date. Your birthday is on a date, it doesn't shift by x hours because you moved to another state.

The old Outlook marked birthdays as all-day events, but stored the value with time-zone, meaning all birthdays of people whose birthday I stored in Belgium were now shifted as I moved to California...

show 2 replies
teifereryesterday at 5:58 PM

> sacrificed to the altar of "web compatibility."

What should they have done instead? Force everybody to detect browser versions and branch based on that, like in the olden days of IE5?

(Serious question, maybe I'm overlooking some smart trick.)

show 3 replies
Kyro38yesterday at 7:00 PM

You might want to play with https://jsdate.wtf/

One can't fathom how weird JS Date can be.

show 1 reply
netghostyesterday at 6:21 PM

If this is comedy, sign me up for tragedy.

This feels like something that must be the root of innumerable small and easily overlooked bugs out there.

show 1 reply
sholladayyesterday at 8:19 PM

Personally, I like that UTC is the default time zone. Processing of dates should happen in a standardized time zone. It’s only when you want to display it that the date should become local.

show 2 replies