Temporal
Dates and times that finally work: immutable, with time zones and calendars.
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| Feature | Desktop | Mobile | |||||
|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Safari | Chrome Android | Firefox Android | Safari iOS | |
| Temporal | 144Chrome: 144 | 144Edge: 144 | 139Firefox: 139 | ✓previewSafari: preview | 144Chrome: 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><!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>Open the example ↗apis-snippets/temporal/ · The repositories will be published soon.
What’s new
Keep in mind
- Pick the right type: PlainDate for birthdays, ZonedDateTime for appointments, Instant for logs.
- With temporal-polyfill (1.0.5), import 'temporal-polyfill/global' only acts if the native one is missing; for non-Gregorian calendars import /full.
- To convert from Date: date.toTemporalInstant().
Further reading
Sources
- Igalia · Temporal reaches Stage 413 Mar 2026
- Safari Technology Preview 24929 Jul 2026
- MDN browser-compat-data 8.1.324 Sep 2026
- npm · temporal-polyfill 1.0.511 Sep 2026