Temporal - JavaScript Reference and Cheatsheet

MDN Docs: Temporal

The Temporal object enables date and time management in various scenarios, including built-in time zone and calendar representation, wall-clock time conversions, arithmetics, formatting, and more. It is designed as a full replacement for the Date object.

Temporal Types:

  • PlainDate - a calendar date, of a specific calendar, without a time or time zone; YYYY-MM-DD [u-ca=calendar_id]
  • PlainTime - a time, without a date or time zone; HH:mm:ss.sssssssss
  • PlainDateTime - a date and time, without time zone; YYYY-MM-DD T HH:mm:ss.sssssssss [u-ca=calendar_id]
  • PlainYearMonth - a year and month, without a day, time, or time zone; YYYY-MM-DD [u-ca=calendar_id]
  • Instant - a unique point in time, with nanosecond precision; YYYY-MM-DD T HH:mm:ss.sssssssss Z/±HH:mm
  • Duration - a difference between two time points; ±P nY nM nW nD T nH nM nS
  • ZonedDateTime - a zoned instant; YYYY-MM-DD T HH:mm:ss.sssssssss Z/±HH:mm [time_zone_id] [u-ca=calendar_id]

Note that the date right now differs between time zones. Despite PlainDate not having a time zone component, getting the current PlainDate via Temporal.Now has an optional time zone parameter to get the now date of a time zone.

A Plain Date, Time, and DateTime

console.log(new Temporal.PlainDate(2025, 2, 5))
console.log(new Temporal.PlainTime())
console.log(new Temporal.PlainTime(13))
console.log(new Temporal.PlainTime(13, 57))
console.log(new Temporal.PlainTime(13, 57, 35))
console.log(new Temporal.PlainTime(13, 57, 35, 777, 888))
console.log(new Temporal.PlainDateTime(2025, 2, 5))
console.log(new Temporal.PlainDateTime(2025, 2, 5, 13, 57, 35, 777, 888, 999))

console.log(new Temporal.PlainDate(2025, 2, 5, "chinese"))
console.log(new Temporal.PlainDateTime(2025, 2, 5, 13, 57, 35, 777, 888, 999, "chinese"))

A Plain Year-Month

Note that the year-month logically represents a year-month but internally holds a day field too, but has no accessible day field like PlainDate does.

console.log(Temporal.PlainYearMonth.from("2025-02"))
console.log(Temporal.PlainYearMonth.from({ year: 2021, month: 5 }))
console.log(Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M05" }))

console.log(Temporal.PlainYearMonth.from("2025-02").add('P1Y').subtract('P1M').until('2050-02'))

console.log(Temporal.PlainYearMonth.from("2025-02-05[u-ca=hebrew]"))
console.log(Temporal.PlainYearMonth.from("2025-02-05[u-ca=hebrew]").year)
console.log(Temporal.PlainYearMonth.from("2025-02-05[u-ca=hebrew]").month)
console.log(Temporal.PlainYearMonth.from("2025-02-05[u-ca=hebrew]").day) // undefined

Now, as a Plain Date, Time, and DateTime

console.log(Temporal.Now.plainDateISO())
console.log(Temporal.Now.plainTimeISO())
console.log(Temporal.Now.plainDateTimeISO())

Now, in a specified time zone:

console.log(Temporal.Now.plainDateISO("Europe/Berlin"))
console.log(Temporal.Now.plainDateISO("CET"))

console.log(Temporal.Now.plainTimeISO("Europe/Berlin"))
console.log(Temporal.Now.plainTimeISO("Asia/Tokyo"))
console.log(Temporal.Now.plainTimeISO("CET"))
console.log(Temporal.Now.plainTimeISO("EST"))

console.log(Temporal.Now.plainDateTimeISO("Europe/Berlin"))
console.log(Temporal.Now.plainDateTimeISO("Asia/Tokyo"))
console.log(Temporal.Now.plainDateTimeISO("CET"))
console.log(Temporal.Now.plainDateTimeISO("EST"))

User Time Zone

console.log(Temporal.Now.timeZoneId())

Instant

Instant is Unix Epoch based.

console.log(Temporal.Now.zonedDateTimeISO())
console.log(Temporal.Now.zonedDateTimeISO("Europe/Berlin"))
console.log(Temporal.Now.zonedDateTimeISO("Asia/Tokyo"))
console.log(Temporal.Now.zonedDateTimeISO("CET"))
console.log(Temporal.Now.zonedDateTimeISO("EST"))

console.log(Temporal.Instant.from("2025-02-05T00Z"))
console.log(Temporal.Instant.from("2025-02-05T13:57:02.777888+02:00"))
console.log(Temporal.Instant.from("2025-02-05T13:57:02.777888+02:00[Europe/Berlin]"))

console.log((new Date()).toTemporalInstant())

console.log(Temporal.Instant.fromEpochMilliseconds(3))
console.log(Temporal.Instant.fromEpochNanoseconds(3n))
console.log(Temporal.Instant.fromEpochNanoseconds(-275248380000000000n))
console.log(Temporal.Instant.fromEpochNanoseconds(355924804000000000n))

Duration

console.log(Temporal.Duration.from({ years: 1 }))
console.log(Temporal.Duration.from('P1Y'))
console.log(Temporal.Duration.from('P1Y').years)
console.log(Temporal.Duration.from('P1Y1M1DT1H1M1.1S'))

console.log(Temporal.Now.plainDateTimeISO().add('PT180S'))
console.log(Temporal.Now.plainDateTimeISO().add('PT2M0.2S').subtract('PT0.5S').since(Temporal.Now.plainDateTimeISO()))

console.log(Temporal.Now.plainDateTimeISO('Europe/Berlin').since(Temporal.Now.plainDateTimeISO('Asia/Tokyo')))
console.log(Temporal.Now.plainDateTimeISO('Asia/Tokyo').since(Temporal.Now.plainDateTimeISO('Europe/Berlin')))

ZonedDateTime

console.log(Temporal.PlainDate.from('2025-02-05').toZonedDateTime('Asia/Tokyo'))
console.log(Temporal.PlainDateTime.from('2025-02-05T08:00:00').toZonedDateTime('Europe/Kiev'))
console.log(Temporal.ZonedDateTime.from('2025-02-05T13:57:35.777888[Europe/Berlin]').withTimeZone('Europe/London'))

console.log(new Temporal.PlainDateTime(2025, 2, 5, 13, 57, 35, 777, 888))
console.log(Temporal.Instant.from("2025-02-05T13:57:02.777888+02:00[Europe/Berlin]"))

console.log(Temporal.ZonedDateTime.from('2025-02-05T13:57:35.777888[Europe/Berlin]').toLocaleString())

Note that the Z offset is not equivalent to +00:00. The Z offset means “the time in UTC is known, but the offset to local time is unknown”.

Note: When setting the time zone name, you rarely want to set it to “UTC”. ZonedDateTime is intended to be displayed to users, but no human lives in the “UTC” time zone. If you don’t know the time zone at construction time but know the wall-clock time, use a Temporal.PlainDateTime. If you know the exact instant, use a Temporal.Instant.