Temporal API: JavaScript Dates, but Better

Temporal API: JavaScript Dates, but Better

·

8 min read

The article has been initially published here.

Introduction

If you've ever worked with Dates in JavaScript, you sure know how clunky and hard to work with they are; that's why, recently, there has been a proposal for a brand new way of working with them, you've guessed it— Temporal API.

Now, what is it?

If we take the Introductionary information that they provide,

Date has been a long-standing pain point in ECMAScript. This is a proposal for Temporal, a global Object'that acts as a top-level namespace (likeMath) that brings a modern date/time API to the ECMAScript language. For a detailed look at some of the problems withDate` and the motivations for Temporal, see: Fixing JavaScript Date.

Why would you want to use it?

Well, there are a couple of reasons, such as:

  • A more straightforward API to work with, both for time, as well as for dates
  • Intuitive naming convention (Plain/Zoned, depending on your need for timezone agnosticism or not)
  • Ease of extracting time/date differences
  • Interoperability between string and object formats
  • Having to deal only with objects representing time or date

I believe that the new Temporal API provides us with a lot of utility that we previously lacked with JS Dates (which had to be compensated through with libraries such as moment.js or date-fns), and a much nicer way of working with a single, global date object (Temporal).

Temporal API Data Types

An essential factor to take into consideration when working with Temporal API is that the data types that it provides are split into Plain & Zoned:

  • Plain, which provides no timezone information
  • Zoned, which represents a date/time with information tied to a particular timezone; it is best suited for scenarios where you need to deal with a particular time within a particular timezone or if you need to format or do time/date difference/addition operations that take timezone-specific information into account

Some key data types that you will most likely work with:

1. PlainDateTime

This is one of the easiest to understand, as it represents a date and time object with no timezone information attached. You can create an instance simply by using the Temporal.Now.plainDateTimeISO method.

This method creates a new PlainDateTime object that uses the local timezone date & time unless no other timezone argument is passed to the method.

2. PlainDate

This object contains date information with no timezone data attached to it. It's best suited for situations where there is no need for any time information.

3. PlainTime

A PlainTime object represents a time that has no date or timezone information associated with it. Something to note about this data type is that there is no associated Temporal.Now.plainTime method, as there cannot be a specific calendar context for a PlainTime object.

4. ZonedDateTime

A ZonedDateTime object is a DateTime object packed with all timezone-related information, making it a perfect fit for cases where daylight savings time is required.

5. Instant

An Instant object is similar to a ZonedDateTime object in terms of representing a specific point in time. However, the difference is that it always contains UTC time and doesn't refer to a particular calendar.

You also cannot pass an object to the from method (which I will address in a second) for an Instant; when you pass a string to the from method, it must include timezone information.

6. PlainMonthDay

A PlainMonthDay is just like a PlainDate; the only difference is that it does not include any year information. This is especially good when working with holidays (December 25th) that always fall on the same day.

Since this is a less common data type, the only ways to create it are with the from method and the constructor.

7. PlainYearMonth

Similarly to PlainMonthDay, a PlainYearMonth object has the same utility, except that you're dealing with Month & Year this time.

Cool Utility Methods That Temporal API Provides

What good would it be if we only had those data types and nothing more? That's why Temporal API comes packed with a wide variety of handy utility methods that compensate for the lacking functionality that JavaScript Dates currently have.

1. Add/Subtract

Adding or subtracting parts of a date in JavaScript is really annoying to do, but with the temporal API, all the data types we have talked about so far have built-in add and subtract methods that make it incredibly easy.

Both functions have the same arguments, the only difference being that one adds while the other subtracts.

The easiest way to use these methods is by passing an object to the add/subtract method with properties for the changes you want to make.

Another nice thing about these functions is they automatically deal with overflow.

For example, if you try to add one month to the date January 31st, that would result in the date February 31st, which doesn't exist. By default, these results will be clamped to the nearest valid date so that they will return February 28th.

You can also disable this behavior, though, with a second options argument.

2. Since/Until

The since and until methods will determine the distance in time between the current temporal date object and another temporal date object.

Similarly to add and subtract the since and until methods are opposites of each other and take the same parameters.

The value returned by these methods is a Temporal.Duration object. Also, you can pass an options argument to these methods to fine-tune how you want the duration calculated.

If you specify the largestUnit then the duration will be determined using that unit as the largest value instead of the default value.

If you specify the smallestUnit then the duration will be determined using that unit as the smallest value instead of the default value. This could result in rounding, which can be further customized with the roundingIncrement and roundingMode options.

3. Equals

The last methods were a bit complex so let's look at a really simple method.

The equals method will return true if the two temporal date objects have the same fields. This is needed since, technically, any comparison done with == or === will be false unless the two objects are the same instance.

4. With

This is one of my favorite helper methods since it covers a huge weak point in JavaScript dates. The with method takes in an object of fields to overwrite on the current date object.

Also, something important to know about this method is that it does not actually change the temporal date object it is called on. Instead, it returns a new temporal date object with the changes applied.

5. Round

Round is a method that returns a new date/time object rounded by a specific unit specified as the argument when called on a Temporal'- like object.

If you want to modify how the rounding is performed, you can instead pass an object that takes smallestUnit, roundingIncrement, and roundingMode parameters.

6. Compare

The last method I want to discuss is the compare method, which is available on the actual data type and not the object instance. This method is pretty much used to make sorting dates easier.

Other Data Types

So far, we've looked over the stars of the show, but there are also a couple more data types that, although you might not use as much, would be helpful to be aware of.

1. Duration

We have mentioned the Duration data type a few times in this article. This data type represents a duration of time and is generally not something you will construct on your own but something you will deal with in the case of comparing dates. If you want, you can create a new Duration with the constructor or the from method.

Similarly to the other aforementioned data types, you can also use the add, subtract, with, and round methods on durations. There are also a few additional helper methods that you will want to know:

2. Timezone

The TimeZone data type is used to represent a specific timezone. The most common scenarios you are likely to use it in would be with the from method or with the Temporal.Now.timeZone method, but you could also use the constructor.

The most crucial helper functions for this data type are getNextTransition and getPreviousTransition, which will return the date/time of the next/previous daylight savings time transition.

3. Calendar

The Calendar data type is the last data type you need to know and is probably the least useful. You can create a calendar using the from method or if you want, use the constructor.

There are no important functions you need to know about this data type, as you're unlikely to use it that often anyway.

Browser Support

Hopefully, after reading all this, you are excited to start trying out the temporal API. The only bad news is that this API is not yet available as it is still in proposal stage 3. There are currently no browsers with any support for this API, but you can use a polyfill if you want to start using this API today.

There are multiple polyfills available for this API, but I found the @js-temporal/polyfill to be a good one. Once you install this library, you can immediately start using the temporal API.

Summary

We all know that JavaScript Dates could be far better, and I really believe that the Temporal API is a vast improvement and the way to go. I was pretty happy that we could try out the Stage 3 Temporal API version, as it provides some insight into an up-and-coming and possible project that would be included in a future version of JavaScript.

I hope you have found this article useful and stirred your interest in the possible new way you will be working with Dates in JavaScript.

Did you find this article valuable?

Support Vlad Mihet by becoming a sponsor. Any amount is appreciated!