Web APIs, todayLab · Alex Harto

Temporal

Dates and times that finally work: immutable, with time zones and calendars.

In your browser: checking…Reviewed 1 Oct 2026

Temporal replaces Date with a type for each case: PlainDate (a date), PlainTime, ZonedDateTime (an instant in a zone), Instant and Duration. Every operation returns a new object and daylight-saving changes are handled correctly.

It has been a standard since March 2026 (TC39 stage 4). It has been in Firefox since 139 and in Chrome and Edge since 144; Safari only has it in Technology Preview. Meanwhile, temporal-polyfill fills the gap.

What it is for

  • Calendars and bookings across time zones
  • Countdowns and exact durations
  • Dates without times that do not shift by a day

Demo

…

One meeting, eight time zones

Where Date gets it wrong

Browser support

Limited availability
FeatureDesktopMobile
ChromeEdgeFirefoxSafariChrome AndroidFirefox AndroidSafari iOS
Temporal144Chrome: 144 144Edge: 144 139Firefox: 139 ✓previewSafari: preview144Chrome: 144 139Firefox: 139 —Safari: No

Compatibility generated on every deploy from MDN browser-compat-data 8.1.3 (24 Sep 2026) · web-features 3.40.0 · checked by hand: 1 Oct 2026

Minimal code

<!doctype html>
<meta charset="utf-8">
<title>Temporal · ejemplo mínimo</title>
<!-- Fechas inmutables con zona horaria. Chrome 144+, Firefox 139+; en Safari, polyfill. -->
<pre id="out"></pre>
<script type="module">
// Usa el Temporal nativo si existe; si no, carga el polyfill
if (typeof Temporal === 'undefined') await import('https://cdn.jsdelivr.net/npm/temporal-polyfill@1.0.5/global.esm.js');

const today = Temporal.Now.plainDateISO();
let christmas = Temporal.PlainDate.from({ year: today.year, month: 12, day: 25 });
if (Temporal.PlainDate.compare(christmas, today) < 0) christmas = christmas.add({ years: 1 });

// 25 oct 2026, 01:30 en Madrid: esa noche se atrasa la hora a las 03:00
const meeting = Temporal.ZonedDateTime.from('2026-10-25T01:30[Europe/Madrid]');
const later = meeting.add({ hours: 2 }); // dos horas reales, con el cambio de hora incluido

document.querySelector('#out').textContent = [
  `Hoy: ${today}`,
  `Días hasta Navidad: ${today.until(christmas).days}`,
  `Reunión: ${meeting}`,
  `Dos horas después: ${later}`,
  `En Nueva York: ${meeting.withTimeZone('America/New_York').toPlainDateTime()}`,
  `1 h 30 min = ${Temporal.Duration.from({ hours: 1, minutes: 30 }).total('minutes')} min`,
].join('\n');
</script>

What’s new

  1. Safari Technology Preview 249 adds the Temporal object.
  2. Temporal reaches TC39 stage 4.
  3. Chrome 144 ships it.

Keep in mind

  1. Pick the right type: PlainDate for birthdays, ZonedDateTime for appointments, Instant for logs.
  2. With temporal-polyfill (1.0.5), import 'temporal-polyfill/global' only acts if the native one is missing; for non-Gregorian calendars import /full.
  3. To convert from Date: date.toTemporalInstant().

Further reading

Sources