• JavaScript Temporal API- A Fix for the Date API
  • Nathan Sebhastian
  • The Nuggets translation Project
  • Permanent link to this article: github.com/xitu/gold-m…
  • Translator: Hoarfroster
  • Proofreader: Chorer, Usualminds

JavaScript’s Date handling API is bad because it implements Date objects directly by copying Java’s Date class, and Java maintainers eventually deprecated many of the Date class methods. In 1997, the Calendar class was created to replace it.

But JavaScript’s Date API hasn’t been further fixed, which is why we’re having the following problems today:

  • DateObjects are mutable
  • Messy apis for date and time calculations (for example, addition and subtraction of days)
  • Only UTC and local time zone are supported
  • Unreliable parsing of dates from strings
  • Calendars other than the Gregorian calendar are not supported

However, since the Date API is currently widely used in various libraries and browser engines, it is not possible to fix the wrong part of it. If we changed its underlying implementation, it would most likely have a disruptive impact on many existing sites and libraries.

The new Temporal API proposal aims to address the issue of the Date API with the following improvements to JavaScript Date and time manipulation:

  • Create and process immutable onlyTemporalobject
  • A simple API for date and time calculations
  • Support for all time zones
  • Strict date resolution in ISO-8601 format
  • Support for non-Gregorian calendars

Keep in mind that the Temporal proposal is currently in phase 2 and is not ready for use in a production environment.

Let’s use code examples to understand what the Temporal API does. All of the Temporal API code in the following is created using Temporal Polyfill.

Immutable date object

The Date object created using JavaScript’s new Date() constructor is mutable, meaning you can change its value after initialization:

let date = new Date("2021-02-20");
console.log(date); / / the 2021-02-20 T00:00:00. 000 z
date.setYear(2000);
console.log(date); / / the 2000-02-20 T00:00:00. 000 z
Copy the code

Although seemingly insignificant, such mutable objects can lead to errors when handled incorrectly, one of which is when we try to add days to the current date.

For example, this is a feature that adds a week to the current date. Since setDate modifies the object itself, we get two objects with the same date value:

function addOneWeek(date) {
    date.setDate(date.getDate() + 7);
    return date;
}

let today = new Date(a);let oneWeekLater = addOneWeek(today);

console.log(today);
console.log(oneWeekLater); // The value is the same as the today variable
Copy the code

Temporal fixes this problem by providing a way not to modify the object directly. For example, here is an example of adding a week using the Temporal API:

const date = Temporal.now.plainDateISO();
console.log(date); / / 2021-02-20
console.log(date.add({days: 7})); / / 2021-02-27
console.log(date); / / 2021-02-20
Copy the code

As shown in the code above, Temporal gives us the.add() method that lets us add the day, week, month, or year to the current date object without changing the original value.

API for date and time calculations

In the previous Temporal example we learned about the.add() method, which helps us perform calculations on date objects. The Date API we are using now only provides methods to get and set Date values, which is not as simple and direct as Temporal.

Temporal also provides us with multiple apis to evaluate date values. For example, the until() method calculates the time difference between firstDate and secondDate.

Using the Date API, we need to manually calculate the number of days between the two dates, as shown below:

const oneDay = 24 * 60 * 60 * 1000;
const firstDate = new Date(2008.1.12);
const secondDate = new Date(2008.1.22);

const diffDays = Math.round(Math.abs((firstDate - secondDate) / oneDay));
console.log(diffDays); / / 10
Copy the code

If it were the Temporal API, we could simply calculate diffDays with the until() method:

const firstDate = Temporal.PlainDate.from('2008-01-12');
const secondDate = Temporal.PlainDate.from('2008-01-22');

const diffDays = firstDate.until(secondDate).days;
console.log(diffDays); / / 10
Copy the code

Other ways to help us do this are:

  • .subtract() method, which is used to subtract the number of days, months, or years from the current date.
  • The.since() method is used to calculate the number of days, months, or years that have elapsed so far for a particular date.
  • The.equals() method, which compares whether two dates are the same.

These apis help us do the calculations without having to create our own solutions.

Support for all time zones

The current Date API tracks the time in UTC on the system, typically generating Date objects in the computer’s time zone, and there is no easy way to manipulate the time zone.

One way I’ve found to manipulate time zones is to use the date.tolocaleString () method, as follows:

let date = new Date(a);let tokyoDate = date.toLocaleString("en-US", {
    timeZone: "Asia/Tokyo"
});
let singaporeDate = date.toLocaleString("en-US", {
    timeZone: "Asia/Singapore"});console.log(tokyoDate); // 2/21/2021, 1:36:46 PM
console.log(singaporeDate); // 2/21/2021, 12:36:46 PM
Copy the code

But since this method returns a string, further date and time operations require us to first convert the string back to the date.

The Temporal API allows you to define time zones when creating dates using the zonedDateTimeISO() method. We can use the.now object to get the current date and time:

let tokyoDate = Temporal.now.zonedDateTimeISO('Asia/Tokyo');
let singaporeDate = Temporal.now.zonedDateTimeISO('Asia/Singapore');

console.log(tokyoDate);
/ / the T13:2021-02-20 by. 435904429 + 09:00 Asia/Tokyo
console.log(singaporeDate);
/ / the T12:2021-02-20 by. 429904404 + 08:00 Asia/Singapore
Copy the code

Since the value returned is still the Temporal date, we can further manipulate it using the methods of Temporal itself:

let date = Temporal.now.zonedDateTimeISO('Asia/Tokyo');
let oneWeekLater = date.add({weeks: 1});

console.log(oneWeekLater);
/ / the T13:2021-02-27 by. 435904429 + 09:00 Asia/Tokyo
Copy the code

The Temporal API follows conventions for using types, where names beginning with Plain have no time zone (.plaindate,.plaintime,.plainDatetime) and.zonedDatetime does the opposite.

Strict date resolution in accordance with ISO-8601 standards

The existing way of parsing dates from strings is unreliable, because when we pass a date string in ISO-8601 format, the return value will vary depending on whether a time zone offset was passed or not.

Consider the following example:

new Date("2021-02-20").toISOString();
/ / the 2021-02-20 T00:00:00. 000 z
new Date("2021-02-20T05:30").toISOString();
/ / the T10:2021-02-20 30:00. 000 z
Copy the code

The first Date constructor above treats the string as UTC+0 time zone, while the second constructor treats the string as UTC-5 (my current time zone), so the return value is adjusted to UTC+0 time zone ** (5:30 UTC-5 equals 10:30 UTC+0) **.

The Temposal proposal addresses this problem by distinguishing between PlainDateTime and ZonedDateTime, as follows:

We need to use the ZonedDateTime object when we want the date to be an object containing the time zone, and the PlainDateTime object when we want the date to be an object containing the time zone.

By creating separate dates with and without time zones, the Temporal API helps us parse the correct date/time combination from the supplied string:

Temporal.PlainDateTime.from("2021-02-20");
// 2021-02-20T00:00:00

Temporal.PlainDateTime.from("2021-02-20T05:30");
// 2021-02-20T05:30:00

Temporal.ZonedDateTime.from("2021-02-20T05:30[Asia/Tokyo]");
// 2021-02-20T05:30:00+09:00[Asia/Tokyo]
Copy the code

As you can see from the example above, the Temporal API does not default to your time zone.

Supports calendars other than the Gregorian calendar

Although the Gregorian calendar is the most widely used calendar system in the world, there are times when we may need to use other calendar systems to view special dates with cultural or religious significance.

The Temporal API allows us to specify a calendar system to be used for date and time calculations.

The NPM Polyfill implementation for the calendar is not yet complete, so we need to try using the withCalendar() method in Browser Polyfill. Visit your Temporal document page and paste the following code into your browser’s console:

Temporal.PlainDate.from("2021-02-06").withCalendar("gregory").day;
/ / 6

Temporal.PlainDate.from("2021-02-06").withCalendar("chinese").day;
/ / 25

Temporal.PlainDate.from("2021-02-06").withCalendar("japanese").day;
/ / 6

Temporal.PlainDate.from("2021-02-06").withCalendar("hebrew").day;
/ / 24

Temporal.PlainDate.from("2021-02-06").withCalendar("islamic").day;
/ / 24
Copy the code

Once the proposal is approved, all possible calendar values in intl.dateTimeFormat will be implemented.

conclusion

The Temporal API is a new proposal for JavaScript that promises to provide a modern date and time API for the language. In my tests based on Polyfill, the API does provide easier date and time manipulation, while allowing for time zone and calendar differences.

The proposal itself is still in phase 3, so if you are interested in learning more and providing feedback, you can visit the Temporal documentation and try the Polyfill NPM package they offer.

  • This article is participating in the “Nuggets 2021 Spring Recruitment Campaign”, click to see the details of the campaign

If you find any mistakes in your translation or other areas that need to be improved, you are welcome to the Nuggets Translation Program to revise and PR your translation, and you can also get the corresponding reward points. The permanent link to this article at the beginning of this article is the MarkDown link to this article on GitHub.


The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. The content covers Android, iOS, front-end, back-end, blockchain, products, design, artificial intelligence and other fields. If you want to see more high-quality translation, please continue to pay attention to the Translation plan of Digging Gold, the official Weibo, Zhihu column.