Questions tagged [ecmascript-temporal]

ECMAScript Temporal provides a set of classes (e.g., Temporal.ZonedDateTime, Temporal.PlainDate, Temporal.PlainTime, Temporal.Instant, etc.) for performing date/time operations in JavaScript apps. It's currently in Stage 3 on the ECMAScript standards track.

Temporal is a global Object that acts as a top-level namespace (like Math), that brings a modern date/time API to the ECMAScript language. For a detailed look at some of the problems with Date, and the motivations for Temporal, see: Fixing JavaScript Date.

Temporal fixes these problems by:

  • Providing easy-to-use APIs for date and time computations
  • First-class support for all time zones, including DST-safe arithmetic
  • Using only immutable objects representing unambiguous dates and times
  • Parsing a strictly specified string format
  • Supporting non-Gregorian calendars

Temporal provides separate ECMAScript classes for date-only, time-only, and other scoped use cases. This makes code more readable and prevents bugs caused by incorrectly assuming 0, UTC, or the local time zone for cases when time zones are unknown.

The Temporal proposal is currently Stage 3. Implementers are currently building Temporal into the ECMAScript engines that power Chrome, Firefox, Safari, Node.js, and other hosts. Polyfills are also available.

In Stage 3, the bar for making API changes is extremely high. Nonetheless, changes may occur as the result of feedback from implementation in JS engines. Editorial changes to the spec and bug fixes to the spec, tests, and docs are also ongoing, as is customary for Stage 3 proposals. Additional tests and documentation content are also being added during Stage 3.

Cookbook

A cookbook to help you get started and learn the ins and outs of Temporal is available here.

API Documentation

The Temporal API follows a convention of using types whose names start with "Plain" (like Temporal.PlainDate, Temporal.PlainTime, and Temporal.PlainDateTime) for objects which do not have an associated time zone. Converting between such types and exact time types (Temporal.Instant and Temporal.ZonedDateTime) can be ambiguous because of time zones and daylight saving time, and the Temporal API lets developers configure how this ambiguity is resolved.

Several important concepts are explained elsewhere: exact time, wall-clock time, time zones, DST, handling ambiguity, and more.

Temporal.Now

  • Temporal.Now.instant() - get the exact time since Unix epoch
  • Temporal.Now.timeZone() - get the current system time zone
  • Temporal.Now.zonedDateTime(calendar) - get the current date and wall-clock time in the system time zone and specified calendar
  • Temporal.Now.zonedDateTimeISO() - get the current date and wall-clock time in the system time zone and ISO-8601 calendar
  • Temporal.Now.plainDate(calendar) - get the current date in the system time zone and specified calendar
  • Temporal.Now.plainDateISO() - get the current date in the system time zone and ISO-8601 calendar
  • Temporal.Now.plainTimeISO() - get the current wall-clock time in the system time zone and ISO-8601 calendar
  • Temporal.Now.plainDateTime(calendar) - get the current system date/time in the system time zone, but return an object that doesn't remember its time zone so should NOT be used to derive other values (e.g. 12 hours later) in time zones that use Daylight Saving Time (DST).
  • Temporal.Now.plainDateTimeISO() - same as above, but return the DateTime in the ISO-8601 calendar
console.log('Initialization complete', Temporal.Now.instant());
// example output:
// Initialization complete 2021-01-13T20:57:01.500944804Z

See Temporal.Now Documentation for detailed documentation.

Temporal.Instant

A Temporal.Instant represents a fixed point in time (called "exact time"), without regard to calendar or location, e.g. July 20, 1969, at 20:17 UTC. For a human-readable local calendar date or clock time, use a Temporal.TimeZone and Temporal.Calendar to obtain a Temporal.ZonedDateTime or Temporal.PlainDateTime.

const instant = Temporal.Instant.from('1969-07-20T20:17Z');
instant.toString(); // => '1969-07-20T20:17:00Z'
instant.epochMilliseconds; // => -14182980000

See Temporal.Instant Documentation for detailed documentation.

Temporal.ZonedDateTime

A Temporal.ZonedDateTime is a timezone-aware, calendar-aware date/time object that represents a real event that has happened (or will happen) at a particular exact time from the perspective of a particular region on Earth, e.g. December 7th, 1995 at 3:24 AM in US Pacific time (in Gregorian calendar). This type is optimized for use cases that require a time zone, including DST-safe arithmetic and interoperability with RFC 5545 (iCalendar).

const zonedDateTime = Temporal.ZonedDateTime.from({
  timeZone: 'America/Los_Angeles',
  year: 1995,
  month: 12,
  day: 7,
  hour: 3,
  minute: 24,
  second: 30,
  millisecond: 0,
  microsecond: 3,
  nanosecond: 500
}); // => 1995-12-07T03:24:30.0000035-08:00[America/Los_Angeles]

As the broadest Temporal type, Temporal.ZonedDateTime can be considered a combination of Temporal.TimeZone, Temporal.Instant, and Temporal.PlainDateTime (which includes Temporal.Calendar).

See Temporal.ZonedDateTime Documentation for detailed documentation.

Temporal.PlainDate

A Temporal.PlainDate object represents a calendar date that is not associated with a particular time or time zone, e.g. August 24th, 2006.

const date = Temporal.PlainDate.from({ year: 2006, month: 8, day: 24 }); // => 2006-08-24
date.year; // => 2006
date.inLeapYear; // => false
date.toString(); // => '2006-08-24'

This can also be converted to partial dates such as Temporal.PlainYearMonth and Temporal.PlainMonthDay.

See Temporal.PlainDate Documentation for detailed documentation.

Temporal.PlainTime

A Temporal.PlainTime object represents a wall-clock time that is not associated with a particular date or time zone, e.g. 7:39 PM.

const time = Temporal.PlainTime.from({
  hour: 19,
  minute: 39,
  second: 9,
  millisecond: 68,
  microsecond: 346,
  nanosecond: 205
}); // => 19:39:09.068346205

time.second; // => 9
time.toString(); // => '19:39:09.068346205'

See Temporal.PlainTime Documentation for detailed documentation.

Temporal.PlainDateTime

A Temporal.PlainDateTime represents a calendar date and wall-clock time that does not carry time zone information, e.g. December 7th, 1995 at 3:00 PM (in the Gregorian calendar).

It can be converted to a Temporal.ZonedDateTime using a Temporal.TimeZone. For use cases that require a time zone, especially using arithmetic or other derived values, consider using Temporal.ZonedDateTime instead because that type automatically adjusts for Daylight Saving Time.

const dateTime = Temporal.PlainDateTime.from({
  year: 1995,
  month: 12,
  day: 7,
  hour: 15
}); // => 1995-12-07T15:00:00
const dateTime1 = dateTime.with({
  minute: 17,
  second: 19
}); // => 1995-12-07T15:17:19

See Temporal.PlainDateTime Documentation for detailed documentation.

Temporal.PlainYearMonth

A date without a day component. This is useful to express things like "the October 2020 meeting".

const yearMonth = Temporal.PlainYearMonth.from({ year: 2020, month: 10 }); // => 2020-10
yearMonth.daysInMonth; // => 31
yearMonth.daysInYear; // => 366

See Temporal.PlainYearMonth Documentation for detailed documentation.

Temporal.PlainMonthDay

A date without a year component. This is useful to express things like "Bastille Day is on the 14th of July".

const monthDay = Temporal.PlainMonthDay.from({ month: 7, day: 14 }); // => 07-14
const date = monthDay.toPlainDate({ year: 2030 }); // => 2030-07-14
date.dayOfWeek; // => 7

See Temporal.PlainMonthDay Documentation for detailed documentation.

Temporal.Duration

A Temporal.Duration expresses a length of time, e.g. 5 minutes and 30 seconds. This is used for date/time arithmetic and for measuring differences between Temporal objects.

const duration = Temporal.Duration.from({
  hours: 130,
  minutes: 20
});

duration.total({ unit: 'second' }); // => 469200

See Temporal.Duration Documentation for detailed documentation.

Balancing

Unlike the other Temporal types, the units in Temporal.Duration don't naturally wrap around to 0: you may want to have a duration of "90 minutes," and you don't want it to unexpectedly turn into "1 hour and 30 minutes."

See Duration balancing for more on this topic.

Temporal.TimeZone

A Temporal.TimeZone represents an IANA time zone, a specific UTC offset, or UTC itself. Time zones translate from a date/time in UTC to a local date/time. Because of this Temporal.TimeZone can be used to convert between Temporal.Instant and Temporal.PlainDateTime as well as finding out the offset at a specific Temporal.Instant.

It is also possible to implement your own time zones.

const timeZone = Temporal.TimeZone.from('Africa/Cairo');
timeZone.getInstantFor('2000-01-01T00:00'); // => 1999-12-31T22:00:00Z
timeZone.getPlainDateTimeFor('2000-01-01T00:00Z'); // => 2000-01-01T02:00:00
timeZone.getPreviousTransition(Temporal.Now.instant()); // => 2014-09-25T21:00:00Z
timeZone.getNextTransition(Temporal.Now.instant()); // => null

See Temporal.TimeZone Documentation for detailed documentation. A conceptual explanation of handling time zones, DST, and ambiguity in Temporal is also available.

Temporal.Calendar

A Temporal.Calendar represents a calendar system. Most code will use the ISO 8601 calendar, but other calendar systems are available.

Dates have associated Temporal.Calendar objects, to perform calendar-related math. Under the hood, this math is done by methods on the calendars.

It is also possible to implement your own calendars.

const cal = Temporal.Calendar.from('iso8601');
const date = cal.dateFromFields({ year: 1999, month: 12, day: 31 }, {});
date.monthsInYear; // => 12
date.daysInYear; // => 365

See Temporal.Calendar Documentation for detailed documentation.

Object relationship

String persistence, parsing, and formatting

All Temporal types have a string representation for persistence and interoperability. The correspondence between types and machine-readable strings is shown below. For more information about string parsing, serialization, and formatting in Temporal (including how Temporal is using industry standards like ISO 8601 and RFC 3339), see String Parsing, Serialization, and Formatting.

Other documentation

  • Ambiguity — Explanation of missing times and double times due to daylight saving and time zone changes.
  • Balancing — Explanation of when Temporal.Duration units wrap around to 0 and when they don't.
  • Why do Temporal instances have a Calendar? — Background about why types like Temporal.PlainDate or Temporal.ZonedDateTime contain a calendar. These extensions are being actively worked on with IETF to get them on a standards track.
18 questions
205
votes
22 answers

How to ISO 8601 format a Date with Timezone Offset in JavaScript?

Goal: Find the local time and UTC time offset then construct the URL in following format. Example URL: /Actions/Sleep?duration=2002-10-10T12:00:00−05:00 The format is based on the W3C recommendation. The documentation says: For example,…
Meow
  • 18,371
  • 52
  • 136
  • 180
29
votes
16 answers

javascript to find leap year

How can I get the code below to work when I have a month of february? Currently it is getting to the day and then stopping before getting to the if to determine whether it is a leap year. if (month == 2) { if (day == 29) { if (year % 4…
Juan Almonte
  • 375
  • 2
  • 8
  • 14
13
votes
3 answers

How to Convert any of the 5 Islamic (Hijri) Calendars' Dates to any of 18 World Calendars without External Libraries or Complex Astronomical Formulas

Searching on both StackOverflow and CodeReview sites, the Method described in this Question/Post has not been attempted; which is to convert the 5 Islamic Calendars' Dates to any of the 18 available calendars in Javascript without the use of…
Mohsen Alyafei
  • 4,765
  • 3
  • 30
  • 42
5
votes
2 answers

How to create instance of `Temporal.Instant` at specific date and time?

I’m struggling with JavaScript’s proposed new Temporal API. What I am trying to do should be straight-forward, yet I fail to find a convincing solution. I must be missing something. The task is as follows: instantiate an object representation of an…
Tim Molendijk
  • 1,016
  • 1
  • 10
  • 14
3
votes
1 answer

How to use 'Temporal' API to Convert between Different Calendar Dates

Using the Temporal.Calendar of the upcoming proposal of the Temporal global Object, the following short function converts between calendar dates (the 18 Calendars recognized in Javascript). Currently, the output date returned by Temporal.Calendar…
Mohsen Alyafei
  • 4,765
  • 3
  • 30
  • 42
3
votes
3 answers

Javascript - Convert a datetime, knowing its time zone, to UTC

I must convert a date time, given its time zone, year, month, day, hours and minutes to an ISO string. For example, given the following parameters: { timeZone: 'Europe/Paris', year: 2020, month: 11, day: 18, hours: 14, minutes: 44, } I want…
3
votes
2 answers

Temporal in Chrome

I try to use Temporal in Chrome, but it fails: Temporal.DateTime.from("2019-11-26T14:58:54.147Z") Uncaught ReferenceError: Temporal is not defined at :1:1 Version: Chromium 78.0.3904.108 How to use Temporal in Chrome? BTW. Above question…
guettli
  • 25,042
  • 81
  • 346
  • 663
2
votes
1 answer

Why does arithmetic on `Temporal.Duration` instances require a `relativeTo` reference calendar date?

The proposed JavaScript Temporal date/time API casually mentions “Interpreting years, months, or weeks requires a reference point” (source), but I fail to understand what is meant by this. More specifically, the following is not possible: let…
Tim Molendijk
  • 1,016
  • 1
  • 10
  • 14
2
votes
2 answers

obtain date object from year, month and day in other locale in JavaScript

I have year, month and day like: let dt = '1401/01/01' in locale like: let locale = 'fa-IR' how can create a date object from it without using some libraries? something like: new Date(dt,locale)
2
votes
2 answers

How to check Daylight Saving Time with Temporal in Javascript?

In case I have a Date and I want to check if the time is DST I can use a method, such as the following: function isDST(d) { let jan = new Date(d.getFullYear(), 0, 1).getTimezoneOffset(); let jul = new Date(d.getFullYear(), 6,…
smartmouse
  • 13,912
  • 34
  • 100
  • 166
1
vote
1 answer

How to increment months using the Temporal API

I am creating a calendar in Angular that has a previous & next month button that currently displays the correct data of that month when I press either the next or previous button only once. The question that I have is how can I increment the months…
1
vote
1 answer

How to adjust the readonly properties for Temporal ZonedDateTime?

Looking into using a polypill for javascript temporal. If I have Temporal.now, how do I adjust that to the 8th hour of today for example. Do I parse out the properties and make a new ZonedDateTime or is there a better way?
Jason Hocker
  • 6,879
  • 9
  • 46
  • 79
1
vote
1 answer

In JavaScript, what is the correct `Temporal` type to use for parsing a particular string?

ECMAScript's new Temporal proposal defines (finally!) a modern API for handling dates and times in JS, including timezone-safe arithmetic and non-Gregorian calendars. I know I can use ISO 8601 or RFC 3339 strings with Temporal. If I have string data…
Justin Grant
  • 44,807
  • 15
  • 124
  • 208
1
vote
1 answer

Date object to Temporal PlainYearMonth

i have a javascript date object as input data, and i want to have a temporal PlainYearMonth output. i tried this, const inputDate = new Date(); const outputData = Temporal.PlainYearMonth.from(inputDate.toTemporalInstant().toString({smallestUnit:…
1
vote
1 answer

How to get Temporal.Duration from two Temporal.Instant in JavaScript?

I have two Instant objects, and need to get one Duration object. How would I do this in JavaScript? const start = Temporal.now.instant(); await doLongOperation(); const finish = Temporal.now.instant(); const duration = ... ?
Vasyl Boroviak
  • 5,959
  • 5
  • 51
  • 70
1
2