New JavaScript Feature: Tackling Temporal Troubles

Author: Fynn Ellie Becker

This blog article provides a hands-on guide on how the new feature in JavaScript, Temporal, helps frontend developers to fix current pitfalls when dealing with times and dates. 

The Trouble with Times

In front end development, time specifications were often a source of frustration—because it is not easy to implement time specifications and time spans without errors. This was previously due, for example, to the fact that the native Date object in JavaScript is outdated, but also to practical hurdles such as different time zones (JavaScript uses the browser’s local time zone by default) of the server, the client, and the users. In this article, we show you how to implement time specifications using the new JavaScript feature Temporal in a practical way.

Let’s take a date, for example 10 June 2025, store it in JavaScript and then print it for displaying on a website. To achieve this, we usually reach for the Date API and create a new date object like this:

We quickly run into issues though when trying to work with this object. Printing it gives us somewhat unexpected results. When we’re in Hamburg, Germany, the printed date is:

In another part of the world, for example in Los Angeles, California, we get:

Even if we only specify a date, the Date API always adds a time component. When printing the date, the API converts to the user’s system time zone.

We can try to work around this issue, for example by explicitly printing the original date in the ISO format:

This might not be the desired output format since user’s are more familiar with their locale’s format. Instead we can use the toLocaleDateString method to format the date in a specific locale:

Which again is printed in the user’s system time zone. In Hamburg this is:

And in Los Angeles:

Let’s force a specific time zone, in this case UTC since we’re not interested in time:

And finally get the desired result:

You need to be aware of all these peculiarities of the Date API just to print a date while ignoring the time component.

Hit list of bad Date API design

  1. Limited time zone support:
    UTC and the user’s system time zone. Should be enough, right?
  2. Mutability:
    Don’t forget to clone your date object or face the consequences.
  3. Few high-level API methods:
    Want to do calculations with dates? Good luck!
  4. Design inconsistencies:
    Zero-based months and the infamous getYear, anyone?

Time for Temporal Technology

Let’s solve all these issues by switching to the Temporal API:

This stores a date without the time component, hence the name “plain” date.

Calling the toLocaleString method immediately gives us the desired result, without having to think about time zone issues:

Calendar day

PlainDate is useful when storing an event that happens on a specific calendar day, for example Easter holiday:

Wall-clock time

The equivalent for time is PlainTime, for example when storing an alarm clock that shouldn’t change with time zones:

Calendar day and wall-clock time

Combine both and get PlainDateTime, a time-zone-independent representation of date and time:

Calendar month and day

To store a recurring event that happens on the same day every year, PlainMonthDay comes in handy:

Calendar year and month

And the final plain API is PlainYearMonth to store a whole month for a specific year:

Time Zones: the final frontier

But sometimes you can’t get away without considering time zones. Let’s add a time component to our date – 10 June 2025, 19:00, Europe/Berlin – and use Temporal to store it:

Calling the toLocaleString method always prints the date in the originally specified time zone:

Of course it’s possible to convert to a different time zone, for example to show the date and time for an online event in a time zone better suited for the user:

One thing to note is the immutability of Temporal objects. Every time you call a method that modifies the date or time, a new Temporal object is returned while the original is left unchanged.

Definitive Durations

So far, Temporal provides a cleaner and more intuitive API replacement for Date. Something completely new to JavaScript are duration objects:

We can also print these with the toLocaleString method in a more human-friendly format:

Durations can be converted to numbers for use in existing JavaScript methods that don’t accept Temporal objects:

Computer, add 2 days

In conjunction with other Temporal APIs, durations can be used for date and time calculations:

How many days until Halloween?

The other way around, Temporal plain and zoned APIs expose methods to calculate durations:

String Theory

Temporal APIs work with one defined ISO format for dates, times, and durations. No more weird parsing issues like with the Date API.

Depending on which API is used, not all components are required, for example PlainDate only uses the date component.

These serialized date, time, and duration representations are useful when communicating with backend APIs where a standardized format is necessary. For internal use in JavaScript, objects can be used instead of ISO strings:

There’s so much more

This article only scratches the surface of the new Temporal APIs. The most comprehensive documentation is available on MDN with lots of examples. The technical specification is available on the TC39 website.

Artur Schwarz

Artur Schwarz

Further questions? Get in touch or book a free meeting!

artur@factorial.io

Recent Session about Temporal

If you are interested in further info about this topic, watch the recording of my session hosted at Factorial on Hamburg on June 10th, 2025 during JavaScript Hamburg Meetup.

Related articles