54 comments

[ 3.3 ms ] story [ 86.0 ms ] thread
I suspect that the arrival of ChatGPT caused traffic to the MDN Date API documentation to go down by at least half.
Go down by half of user traffic, go up 10x of crawler traffic.
The Date API is fine and relatively normalized. Once you understand it it's very easy to work with. It's biggest problem is that it simply does not support timezones, which is the main reason to use Temporal.
Built a scheduler with pretty much all my moment/moment-tz questions answered through ChatGPT. One of the things it excels at, crawling long lived API documentation, answers, etc.
Is Temporal even in though? Last I checked (last year or so), I had to use some bleeding edge version of Firefox to get it, and absolutely nothing else had it. I do agree though it's lovely, and I'd love to see native support for it.
typo:

    // A numeric string between 32 and 49 is assumed to be in the 2000s:
    console.log( new Date( "49" ) );
    // Result: Date Fri Jan 01 2049 00:00:00 GMT-0500 (Eastern Standard Time)

    // A numeric string between 33 and 99 is assumed to be in the 1900s:
    console.log( new Date( "99" ) );
    // Result: Date Fri Jan 01 1999 00:00:00 GMT-0500 (Eastern Standard Time)
the second interval should start at 50, not 33
Late by a decade or more (JSR310 was released in 2014), but still a good development. I've tried convincing colleagues to use js-joda in the past but they thought they were keeping it simple by sticking to moment.js. They weren't.
I am not sure if I like mixing value and formatting in single object. On other hand anything will be an improvement compared to that terrible old API.
Temporal objects do not store formatting information. Unless you mean e.g. dropping the time, using a different time zone, etc - but those aren't formatting changes, they logically change the semantics of the data. Just like `myInt += 1` is not changing the "formatting" of `myInt`.

Remember: Date and Temporal objects are logically different things. A Date represents an absolute point in time (a timestamp), while a Temporal object represents a human time (calendar date, clock time, time zone). The fact that Dates are used to represent human time for lack of a better structure is the entire problem statement - the hole that all these other APIs like Temporal try to fill in.

> My complaint is about more than parsing or syntax or “developer ergonomics” ... My problem with Date is that using it means deviating from the fundamental nature of time itself.

I don't really have a problem with the substance of this blog post. I have a problem with this exaggerated writing style. It means deviating from the fundamental purpose of writing itself!

I had to scroll all the way to the end to find the actual point, and it was underwhelming.

> Unlike Date, the methods we use to interact with a Temporal object result in new Temporal objects, rather than requiring us to use them in the context of a new instance

Bro, just be honest. This entire blog post was totally about developer ergonomics and that's okay. We all hate the way Date works in javascript.

It's not an exaggeration - you're used to dramatic phrases that use similar wording ("fundamental nature of time itself"), but in this case it's a regular old literally-true statement. Date is used to represent two things: Timestamps and human times (date, time, tz). But it only actually represents the former. Using it to represent the latter is a hack we simply put up with.
Pedantically, Temporal also deviates from the fundamental nature of time itself. Temporal.Instant? In which accelerating frame of reference? It supports equality, which is a nonsense concept.
Checking its API, I'm surprised that Temporal.Duration has a constructor with many parameters for years, months, days, ... all the way to nanoseconds, while Temporal.Instant has no way at all to create it given a current year/month/day, only from unix timestamp equivalents (or strings)

That seems to be functionality you'd want to have? Or is the intention you convert your numbers to string first and then back to a Temporal.Instant?

Not yet, adoption is kind of poor atm.

This is not to detract from the quality of the article which is a top-notch introduction to this new API.

Except Temporal is not, in fact, out.

https://caniuse.com/temporal

The current global availability of native Temporal is 1.81%. For context, IE11(!) has a higher global usage than Temporal has native support. For my organization, this likely means we're years from being able to use Temporal in production, because getting the polyfills approved is such a hassle.

Keep in mind that even as of December last year, Chrome didn't ship with it yet (i.e. support is less than one month old). Safari still does not.

Good article, but “Java deprecated their Date way back in 1997” is not exactly true. They deprecated a lot of methods and constructors in JDK1.1 when Calendar was introduced, but the class itself was never deprecated and it was the preferred way to represent a point in time until the “modern” approach was provided in java.time in JDK8 (c2014)
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...

Local time is unparsable, and this case is only human readable, because humans can handle ambiguity ad hoc. Parsing it as UTC is a reasonable default for a machine parser, at least the only workable one.
I do find it annoying how the Temporal API, just like nearly all other datetime APIs, has 0 support for querying leap-second information in any shape or form. Suggested workarounds like temporal-tai all require plugging in a leap-second file and keeping it updated, which is especially painful for client-side JS, where you can't just download a leap-second file from someone else's site thanks to the SOP. Meanwhile, browsers update on a cadence more than sufficient to keep an up-to-date copy, but the datetime APIs refuse to expose leap-second info because they're too committed to "only UTC is in-scope for this project".

(The context is that I want to write some JS tools for astronomical calculations, but UTC conversions need leap-second info, so this trend makes it impossible to write something that Just Works™.)

> When an immutable value is assigned to a variable, the JavaScript engine creates a copy of that value and stores the copy in memory

Not exactly. The language doesn't specify whether the value is copied or not and, precisely because values are immutable, there's no way for a user to tell if it was or wasn't.

For example, strings are also immutable value types, but you can be certain that no JS engine is fully copying the entire string every time you assign one to a variable or pass it to a parameter.

There's a lot wrong with Javascript's Date, but the fact that it's an object is is not really in the top 10.

Would it have been nice if the Date object had been immutable? Sure, but the fact that changing the mutable object does indeed change the object shouldn't be a shock

Yes, you should use shiny new library instead of the glitchy javascript standard..

Unless you want your website to run in browsers older than a year

Maybe in 10 years we can start using the shiny new thing?

So, hold on--the author's soul-breaking complaint isn't all of the "quirks" and inconsistencies with the Date functions, but rather the fact that it's an object? Specifically, an object with mutable properties in a language when all objects have mutable properties?

I mean, the author's conclusion is correct. But I disagree with the rationale. It's like hating an evil dictatorship because they use the wrong font in their propaganda.

The article is super weird. It never mentions Date.now(). It dances around the subject and exhaustively mentions the equivalent convention for Temporal.

If you want Date to act like Temporal then only use Date.now() as your starting point. It generates the number of milliseconds since 1 Jan 1970. That means the starting output is a number type in integer form. It does not represent a static value, but rather the distance between now and some universal point in the past, a relationship. Yes, Temporal is a more friendly API, but the primary design goal is to represent time as a relational factor.

Then you can format the Date.now() number it into whatever other format you want.

  >It wholesale does not understand the concept of daylight savings time
While we're nitpicking (which I wholly support, by the way) it's "daylight saving time."

Cheers, great read.