The ECMAScript 2026 release includes a major new feature: the Temporal API. This is a comprehensive date and time library that addresses many of the shortcomings of the existing Date object in JavaScript.
Date was always overloaded. It tried to represent an exact timestamp, a local date and time, UTC, parsing, formatting, calendar math, and time zone behavior with one mutable object and a pile of legacy rules. Temporal fixes that by splitting the problem into explicit, immutable value types.
ECMAScript 2026 not only introduces the Temporal API, but also includes smaller features. You can find a summary of those in my other blog post: ES2026: The smaller features.
Namespace ¶
The Temporal API adds a new global namespace Temporal that contains the following types and utilities:
- Instant - an exact point on the timeline
- Now - a collection of utilities for accessing the current time
- PlainDate - a calendar date without time or time zone
- PlainDateTime - a calendar date and time without time zone
- PlainMonthDay - a month and day without a year
- PlainTime - a wall-clock time without date or time zone
- PlainYearMonth - a year and month without a day
- ZonedDateTime - a date and time with an associated time zone
- Duration - a span of time expressed in units
The naming convention is that every type starting with "Plain" is time-zone-unaware. ZonedDateTime is the type that includes time zone information.
One of the core design principles of the Temporal API is that all types are immutable. This means that any operation that modifies a Temporal value returns a new value instead of changing the original.
Instant ¶
The Temporal.Instant type represents an exact point on the timeline. It is the most basic and fundamental type in the Temporal API, and it is used as the basis for all other types. An Instant is immutable and has no calendar or time zone information. It always goes forward and does not observe daylight saving time or any other local time adjustments.
const instant = Temporal.Instant.from("2026-03-12T14:00:00Z");
console.log(instant.toString());
// 2026-03-12T14:00:00Z
const fromMs = Temporal.Instant.fromEpochMilliseconds(1773324000000);
console.log(fromMs.toString());
// 2026-03-12T14:00:00Z
const fromNs = Temporal.Instant.fromEpochNanoseconds(1773324000123456789n);
console.log(fromNs.toString());
// 2026-03-12T14:00:00.123456789Z
Z is the standard suffix for UTC time in RFC 9557. The from() method parses a string in RFC 9557 format. The fromEpochMilliseconds() and fromEpochNanoseconds() methods create an Instant from a numeric timestamp.
This type can be useful for database timestamps, log entries, audit trails, event ordering, and values exchanged between services. It is the most precise and unambiguous way to represent a moment in time in JavaScript.
You find a list of all supported methods on the MDN documentation.
Now ¶
The Temporal.Now namespace provides utilities for accessing the current time. It includes methods for getting the current Instant, the current time zone, and the current local date and time in various formats.
const nowInstant = Temporal.Now.instant();
const localZone = Temporal.Now.timeZoneId();
const localDate = Temporal.Now.plainDateISO();
const localTime = Temporal.Now.plainTimeISO();
const localDateTime = Temporal.Now.plainDateTimeISO();
const localZonedDateTime = Temporal.Now.zonedDateTimeISO();
console.log(localZone);
// Europe/Zurich
console.log(nowInstant.toString());
// 2026-03-12T14:22:31.123456789Z
console.log(localDate.toString());
// 2026-03-12
console.log(localTime.toString());
// 15:22:31.123456789
console.log(localDateTime.toString());
// 2026-03-12T15:22:31.123456789
console.log(localZonedDateTime.toString());
// 2026-03-12T15:22:31.123456789+01:00[Europe/Zurich]
PlainDate ¶
Temporal.PlainDate is a calendar date without time or time zone. This can be useful for values like birthdays, due dates, holidays, billing cycle anchors, and anything that should stay a date no matter where the user is.
Similar to the Instant object, you can create a PlainDate from a string or from an object. The string format must be in the RFC 9557 format. The object format allows you to specify the year, month, and day as properties.
const billingDate = Temporal.PlainDate.from("2026-01-31");
const birthday = Temporal.PlainDate.from({ year: 1990, month: 5, day: 15 });
console.log(billingDate.toString());
// 2026-01-31
console.log(birthday.toString());
// 1990-05-15
Note that months start from 1 (January) and not 0, which is a common source of confusion with the Date object.
PlainDateTime ¶
Temporal.PlainDateTime represents a calendar date and time without time zone. This can be useful for values like a timestamp typed into a form before choosing a time zone, a recurring local appointment template, or a date-time stored in business rules where the zone is handled separately.
Similar to the previous types, you can create a PlainDateTime from a string or from an object. The string format must be in the RFC 9557 format. The object format allows you to specify the year, month, day, hour, minute, second, millisecond, microsecond, and nanosecond as properties.
const draftPublishAt = Temporal.PlainDateTime.from("2026-04-02T15:30");
const anotherPublishAt = Temporal.PlainDateTime.from({
year: 2026,
month: 4,
day: 2,
hour: 15,
minute: 30
});
console.log(draftPublishAt.toString());
// 2026-04-02T15:30:00
console.log(anotherPublishAt.toString());
// 2026-04-02T15:30:00
PlainMonthDay ¶
Temporal.PlainMonthDay represents a month and day without a year. This can be useful for recurring annual dates like birthdays, anniversaries, yearly renewal reminders, and holiday definitions.
const swissNationalDay = Temporal.PlainMonthDay.from("08-01");
console.log(swissNationalDay.toString());
// 08-01
const christmas = Temporal.PlainMonthDay.from({ month: 12, day: 25 });
console.log(christmas.toString());
// 12-25
PlainTime ¶
Temporal.PlainTime represents a wall-clock time without date or time zone. This can be useful for storing opening hours, recurring alarm times, and business rules like "orders placed before 17:00 ship today".
const closeOfBusiness = Temporal.PlainTime.from("17:00:00");
console.log(closeOfBusiness.toString());
// 17:00:00
const openingTime = Temporal.PlainTime.from({
hour: 9,
minute: 30
});
console.log(openingTime.toString());
// 09:30:00
PlainYearMonth ¶
Temporal.PlainYearMonth represents a year and month without a day. This can be useful for credit card expiration months, monthly reporting windows, recurring monthly schedules, and interfaces where the user picks a month, not a day.
const reportingMonth = Temporal.PlainYearMonth.from("2026-10");
console.log(reportingMonth.toString());
// 2026-10
const expirationDate = Temporal.PlainYearMonth.from({ year: 2026, month: 2 });
console.log(expirationDate.toString());
// 2026-02
ZonedDateTime ¶
Temporal.ZonedDateTime is a date and time with an associated time zone. This is the type to use when your logic depends on human local time in a real region. It combines an exact instant, a time zone identifier, and a calendar. It is the broadest Temporal type and the closest conceptual replacement for most existing Date usage.
const standup = Temporal.ZonedDateTime.from(
"2026-03-12T09:30:00+08:00[Asia/Hong_Kong]"
);
console.log(standup.toString());
// 2026-03-12T09:30:00+08:00[Asia/Hong_Kong]
const secondStandup = Temporal.ZonedDateTime.from({
year: 2026,
month: 3,
day: 12,
hour: 14,
minute: 30,
timeZone: "Asia/Hong_Kong"
});
console.log(secondStandup.toString());
// 2026-03-12T14:30:00+08:00[Asia/Hong_Kong]
To change the time zone of a ZonedDateTime without changing the instant, you can use the withTimeZone() method. This allows you to switch time zones while preserving the exact moment in time.
const trade = Temporal.ZonedDateTime.from(
"2026-06-01T09:30:00-04:00[America/New_York]"
);
const singapore = trade.withTimeZone("Asia/Singapore");
console.log(trade.toInstant().equals(singapore.toInstant()));
// true
console.log(singapore.toString());
// 2026-06-01T21:30:00+08:00[Asia/Singapore]
Output as strings ¶
All Temporal date/time types have a toString() method that returns a string representation of the value in RFC 9557 format.
const invoiceDue = Temporal.ZonedDateTime.from(
"2026-12-31T23:00:00-05:00[America/New_York]"
);
console.log(invoiceDue.toString());
// 2026-12-31T23:00:00-05:00[America/New_York]
In addition to the toString() method, you can also use toLocaleString() to get a localized string representation of the value. For Temporal.ZonedDateTime, the locale comes from the locales argument, while the time zone comes from the value itself.
const meetingTime = Temporal.ZonedDateTime.from(
"2026-04-02T15:30:00+02:00[Europe/Paris]"
);
console.log(meetingTime.toLocaleString());
// 4/2/2026, 3:30:00 PM GMT+2
The output of toLocaleString() can be customized. The first argument is the locale to use for formatting. The second argument is an options object that lets you specify the date and time components to include in the output, as well as the formatting style. In this example, we specify that we want to include the date with a long format, which results in a more human-readable output.
const meetingTime = Temporal.ZonedDateTime.from(
"2026-04-02T15:30:00+02:00[Europe/Paris]"
);
console.log(meetingTime.toLocaleString("de-DE", { dateStyle: "long" }));
// 2. April 2026
You can find a description of the supported options for toLocaleString() in the MDN documentation for Intl.DateTimeFormat.
Mutate with with() ¶
As mentioned above, all Temporal types are immutable. To create a modified version of a Temporal value, you can use the with() method, which takes an object with the fields you want to change and returns a new Temporal value with those fields updated.
const original = Temporal.PlainDateTime.from("2026-04-02T15:30");
const modified = original.with({ minute: 45, hour: 17 });
console.log(original.toString());
// 2026-04-02T15:30:00
console.log(modified.toString());
// 2026-04-02T17:45:00
Comparing ¶
Temporal gives you instance equality checks and, for most types, static comparison helpers, which makes sorting and ordering straightforward.
compare() is a static method that takes two Temporal values of the same type and returns -1 if the first value is earlier than the second, 1 if the first value is later than the second, and 0 if they are equal. The equals() method is an instance method that checks if two Temporal values are exactly equal.
const morningCutoff = Temporal.PlainTime.from("11:30");
const submittedAt = Temporal.PlainTime.from("10:45");
console.log(Temporal.PlainTime.compare(submittedAt, morningCutoff) < 0);
// true
console.log(submittedAt.equals(morningCutoff));
// false
In the following example, compare() returns 0 because on the timeline the two ZonedDateTime values represent the same instant, but equals() returns false because they have different time zone information. To get the same result as compare(), we can convert both values to Instant and then compare them.
const first = Temporal.ZonedDateTime.from(
"2026-06-01T09:30:00-04:00[America/New_York]"
);
const second = Temporal.ZonedDateTime.from(
"2026-06-01T15:30:00+02:00[Europe/Paris]"
);
const comparison = Temporal.ZonedDateTime.compare(first, second);
console.log(comparison);
// 0
console.log(first.equals(second));
// false
console.log(first.toInstant().equals(second.toInstant()));
// true
Conversions between types ¶
Temporal types provide conversion methods where the target type can be derived from the available information. In some cases, you need to provide extra information to complete the conversion. For example, you can convert a PlainDateTime to a ZonedDateTime by attaching a time zone, or you can convert a ZonedDateTime to an Instant by dropping the time zone-specific representation.
const localMeeting = Temporal.PlainDateTime.from("2026-07-01T09:00");
const parisMeeting = localMeeting.toZonedDateTime("Europe/Paris");
console.log(parisMeeting.toString());
// 2026-07-01T09:00:00+02:00[Europe/Paris]
const invoiceDue = Temporal.ZonedDateTime.from(
"2026-12-31T23:00:00-05:00[America/New_York]"
);
const dueInstant = invoiceDue.toInstant();
console.log(dueInstant.toString());
// 2027-01-01T04:00:00Z
Another common conversion is to get the current time as an Instant and then convert it to a ZonedDateTime in a specific time zone.
const nowInstant = Temporal.Now.instant();
const localZone = Temporal.Now.timeZoneId();
const localZonedDateTime = nowInstant.toZonedDateTimeISO(localZone);
console.log(localZonedDateTime.toString());
// 2026-03-27T16:17:22.12211499+01:00[Europe/Zurich]
When you convert from an incomplete type like PlainMonthDay to a complete type like ZonedDateTime, you need to provide the missing information. For example, to convert a PlainMonthDay to a ZonedDateTime, you first need to attach a year to get a PlainDate, and then attach a time and time zone to get a ZonedDateTime.
const swissNationalDay = Temporal.PlainMonthDay.from("08-01");
const thisYearSwissNationalDay = swissNationalDay.toPlainDate({ year: Temporal.Now.plainDateISO().year }).toZonedDateTime({
timeZone: "Europe/Zurich",
plainTime: Temporal.PlainTime.from("12:00")
});
console.log(thisYearSwissNationalDay.toString());
// 2026-08-01T12:00:00+02:00[Europe/Zurich]
The other direction is similar: the relevant to... method drops the fields that are not needed for the target type and returns the appropriate value.
To get from a ZonedDateTime to a PlainMonthDay, you first drop the time zone and time information to get a PlainDate, and then convert that to a PlainMonthDay or a PlainYearMonth.
const today = Temporal.Now.zonedDateTimeISO();
const monthDay = today.toPlainDate().toPlainMonthDay();
console.log(monthDay.toString());
// 03-27
const monthYear = today.toPlainDate().toPlainYearMonth();
console.log(monthYear.toString());
// 2026-03
Metadata ¶
The Temporal types include properties that expose metadata about the value. For example, PlainDate has properties like inLeapYear, daysInMonth, and dayOfWeek that provide information about the calendar date. ZonedDateTime has properties like timeZoneId and calendarId that provide information about the time zone and calendar system.
const releaseDay = Temporal.PlainDate.from("2028-02-29");
console.log(releaseDay.inLeapYear);
// true
console.log(releaseDay.daysInMonth);
// 29
console.log(releaseDay.daysInYear);
// 366
console.log(releaseDay.dayOfWeek);
// 2
console.log(releaseDay.dayOfYear);
// 60
const dstDay = Temporal.ZonedDateTime.from(
"2026-03-29T12:00:00+02:00[Europe/Berlin]"
);
const hoursInDay = dstDay.hoursInDay;
console.log(hoursInDay);
// 23
const timeZone = dstDay.timeZoneId;
console.log(timeZone);
// Europe/Berlin
const calendar = dstDay.calendarId;
console.log(calendar);
// iso8601
This metadata is also useful for practical recipes. For example, to get the last day of a month, you can ask Temporal how many days that month has and then build the final date from that.
const month = Temporal.PlainYearMonth.from("2026-02");
const lastDayOfMonth = month.toPlainDate({ day: month.daysInMonth });
console.log(lastDayOfMonth.toString());
// 2026-02-28
If you already have a PlainDate, the same recipe is even shorter because the date itself already knows how many days are in its month.
const invoiceDate = Temporal.PlainDate.from("2028-02-03");
const monthEnd = invoiceDate.with({ day: invoiceDate.daysInMonth });
console.log(monthEnd.toString());
// 2028-02-29
Duration + Arithmetic ¶
Adding and subtracting durations ¶
Most Temporal types have add() and subtract() methods that take a Temporal.Duration object or another duration-like value. This allows you to perform calendar-aware arithmetic on dates and times. For example, you can add 1 month to January 31 and get February 28, or you can add 1 day to a date that falls on a daylight saving transition and get the correct next day.
const billingDate = Temporal.PlainDate.from("2026-01-31");
const nextBillingDate = billingDate.add({ months: 1 });
console.log(nextBillingDate.toString());
// 2026-02-28
const beforeDst = Temporal.ZonedDateTime.from(
"2026-03-29T00:30:00+00:00[Europe/London]"
);
const plusOneHour = beforeDst.add({ hours: 1 });
console.log(plusOneHour.toString());
// 2026-03-29T02:30:00+01:00[Europe/London]
const closeOfBusiness = Temporal.PlainTime.from("17:00:00");
const warning = closeOfBusiness.subtract({ minutes: 15 });
console.log(warning.toString());
// 16:45:00
Calculating differences ¶
To calculate a difference between two Temporal values, you can use the until() or since() methods, which return a Temporal.Duration object that represents the difference in calendar units. You can specify the largest unit to use in the duration with the largestUnit option. For example, if you want to calculate the difference between two PlainDateTime values in terms of days, hours, and minutes, you can use largestUnit: "day".
until() calculates other - this. A duration can be negative when the other value is earlier than this value. Negative durations are represented with a leading - in the duration string.
const start = Temporal.PlainDateTime.from("2026-04-02T09:15");
const end = Temporal.PlainDateTime.from("2026-04-03T12:45");
const diff = start.until(end, { largestUnit: "day" });
console.log(diff.toString());
// P1DT3H30M
If we want to calculate the difference in hours instead, we can use largestUnit: "hour".
const diffInHours = start.until(end, { largestUnit: "hour" });
console.log(diffInHours.toString());
// PT27H30M
The duration format is the standard ISO 8601 duration format, which starts with a P (for "period") and then includes the number of years, months, days, hours, minutes, and seconds in the duration. The T separates the date part from the time part. For example, P1DT3H30M means 1 day, 3 hours, and 30 minutes. In this format, Y means years, D means days, H means hours, and S means seconds. M means months before the T and minutes after the T. If a unit is not present in the duration, it means that the value is zero for that unit.
since() does the opposite of until(): it calculates this - other.
const diffSince = end.since(start, { largestUnit: "day" });
console.log(diffSince.toString());
// P1DT3H30M
const diffReverse = start.since(end, { largestUnit: "day" });
console.log(diffReverse.toString());
// -P1DT3H30M
You can also take a duration and add or subtract it from a Temporal value to get a new Temporal value. For example, you can add a duration of 1 day, 3 hours, and 30 minutes to a PlainDateTime to get a new PlainDateTime that is 1 day, 3 hours, and 30 minutes later.
const duration = Temporal.Duration.from("P1DT3H30M");
const newDateTime = start.add(duration);
console.log(newDateTime.toString());
// 2026-04-03T12:45:00
You can also create a duration from an object with the desired units, like this:
const durationFromObject = Temporal.Duration.from({ days: 1, hours: 3, minutes: 30 });
const newDateTimeFromObject = start.add(durationFromObject);
console.log(newDateTimeFromObject.toString());
// 2026-04-03T12:45:00
When you add a duration to a Temporal value, the arithmetic is calendar-aware. This means that it takes into account things like leap years, daylight saving time transitions, and varying month lengths. For example, if you add 1 month to January 31, you get February 28 (or 29 in a leap year), not March 3.
const jan31 = Temporal.PlainDate.from("2026-01-31");
const feb28 = jan31.add({ months: 1 });
console.log(feb28.toString());
// 2026-02-28
Converting duration units with total() ¶
The total() method allows you to convert a Temporal.Duration into a single unit of time. For example, you can convert a duration of 2 hours, 30 minutes, and 45 seconds into the total number of minutes or seconds.
const timeSpent = Temporal.Duration.from({
hours: 2,
minutes: 30,
seconds: 45
});
console.log(timeSpent.total({ unit: "minute" }));
// 150.75
console.log(timeSpent.total({ unit: "second" }));
// 9045
For example, you can calculate how many days until your next birthday by calculating the duration between today and your next birthday, and then converting that duration into total days.
const today = Temporal.PlainDate.from("2026-04-02");
const nextBirthday = Temporal.PlainDate.from("2026-07-15");
const durationUntilBirthday = today.until(nextBirthday);
console.log(durationUntilBirthday.toString());
// P104D
console.log(durationUntilBirthday.total({ unit: "day", relativeTo: today }));
// 104
Rounding ¶
Several Temporal types, including PlainDateTime, ZonedDateTime, and Duration, support round(). This method allows you to round a value to the nearest unit of time. For example, you can round a PlainDateTime to the nearest hour, or you can round a ZonedDateTime to the nearest day. The rounding is also calendar-aware, so it takes into account things like leap years and daylight saving time transitions.
const startDateTime = Temporal.PlainDateTime.from("2026-04-02T08:30:45");
const startRoundedToDay = startDateTime.round({ smallestUnit: "day" });
console.log(startRoundedToDay.toString());
// 2026-04-02T00:00:00
const endDateTime = Temporal.PlainDateTime.from("2026-04-02T15:30:45");
const endRoundedToDay = endDateTime.round({ smallestUnit: "day" });
console.log(endRoundedToDay.toString());
// 2026-04-03T00:00:00
Here we see that by default round() behaves similarly to Math.round(), so it rounds to the nearest unit. Times after 12:00:00 round up to the next day, and times before 12:00:00 round down to the start of the same day. If you want to always round down, you can use roundingMode: "floor", and if you want to always round up, you can use roundingMode: "ceil". See more information about the rounding modes in the MDN documentation.
const startRoundedUp = startDateTime.round({ smallestUnit: "day", roundingMode: "ceil" });
console.log(startRoundedUp.toString());
// 2026-04-03T00:00:00
You can also specify a roundingIncrement to round to increments of the specified unit. For example, you can round a ZonedDateTime to the nearest 30-minute increment.
const event = Temporal.ZonedDateTime.from(
"2026-03-12T09:37:00+02:00[Africa/Johannesburg]"
);
const slot = event.round({
smallestUnit: "minute",
roundingIncrement: 30,
roundingMode: "halfExpand"
});
console.log(slot.toString());
// 2026-03-12T09:30:00+02:00[Africa/Johannesburg]
You can also round Duration values. For example, you can round a duration of 1 day, 3 hours, and 30 minutes to the nearest hour.
const duration = Temporal.Duration.from("P1DT3H30M");
const roundedDuration = duration.round({ smallestUnit: "hour" });
console.log(roundedDuration.toString());
// P1DT4H
DST-safe arithmetic ¶
The API also takes DST transitions into account. If you add 1 hour to a time that falls on a DST transition, you get the correct next time, even if it means skipping an hour or repeating an hour.
In London the DST transition in spring 2026 happens on March 29, when the clock jumps from 01:00 to 02:00. If you add 1 hour to 00:30 on that day, you get 02:30, not 01:30, because 01:30 does not exist on that day in that time zone.
const beforeDst = Temporal.ZonedDateTime.from(
"2026-03-29T00:30:00+00:00[Europe/London]"
);
const plusOneHour = beforeDst.add({ hours: 1 });
console.log(beforeDst.toString());
// 2026-03-29T00:30:00+00:00[Europe/London]
console.log(plusOneHour.toString());
// 2026-03-29T02:30:00+01:00[Europe/London]
Calendars ¶
This is a major capability that Date never had as a first-class feature.
Temporal values that contain calendar dates are calendar-aware. Most code will use the default iso8601 calendar, but the API is designed to support real calendar arithmetic in other calendar systems too. You can find the list of supported calendars in the MDN documentation.
To work with a specific calendar, you can use the u-ca suffix key in the string format, specify the calendar property in object input, or reinterpret an existing value with withCalendar(). For example, here we reinterpret an ISO date through the Thai Buddhist calendar:
const thaiDate = Temporal.Now.plainDateISO().withCalendar("buddhist");
console.log(thaiDate.toString());
// 2026-03-12[u-ca=buddhist]
console.log(thaiDate.year);
// 2569
Note that the output of toString() uses the RFC 9557 format. The numeric date part stays in ISO 8601 form, while the attached calendar is emitted as an annotation suffix in square brackets. The year property shows you the year in the Buddhist calendar.
If you want to see the date formatted according to the rules of the attached calendar, you can use toLocaleString() with the appropriate locale and calendar options.
const thaiDate = Temporal.Now.plainDateISO().withCalendar("buddhist");
console.log(thaiDate.toLocaleString("th-TH", { calendar: "buddhist", dateStyle: "full" }));
// วันศุกร์ที่ 27 มีนาคม พ.ศ. 2569
console.log(thaiDate.toLocaleString("en", { calendar: "buddhist", dateStyle: "full" }));
// Friday, March 27, 2569 BE
Calendar properties ¶
Calendar properties are available on Temporal values that have calendar information. For example, if you create a PlainDate with the Japanese calendar, you can access the era, and eraYear properties to get information about the era and year in the era.
const date = Temporal.PlainDate.from("2026-03-12[u-ca=japanese]");
console.log(date.era);
// reiwa
console.log(date.eraYear);
// 8
Or for the Thai Buddhist calendar, the eraYear property gives you the year in the Buddhist era, which is 543 years ahead of the Gregorian calendar.
const thaiDate = Temporal.PlainDate.from("2026-03-12[u-ca=buddhist]");
console.log(thaiDate.era);
// be
console.log(thaiDate.eraYear);
// 2569
Using Temporal today ¶
It is quite early in the ES2026 release cycle, and the API is not yet universally supported. Before you use the Temporal API, check the current compatibility tables for your target runtimes. Can I Use gives you a good overview of where Temporal is supported.
If you don't want to wait until Temporal is natively supported in all your target environments, you can use a polyfill. MDN currently lists these two polyfills: @js-temporal/polyfill and temporal-polyfill.
npm install @js-temporal/polyfill
import { Temporal } from "@js-temporal/polyfill";
console.log(Temporal.Now.zonedDateTimeISO().toString());
Wrapping Up ¶
The Temporal API is a huge improvement over Date. It gives JavaScript a modern date and time system that supports real-world use cases with explicit semantics.
For more in-depth information, see the MDN Temporal reference.