
Temporal: la nuova API JavaScript che (finalmente) sostituisce Date
Cosa non va nel vecchio oggetto Date, come Temporal lo risolve, i tipi principali (PlainDate, ZonedDateTime, Duration...) e a che punto è il supporto nel 2026.
Date è una delle parti più vecchie e più criticate di JavaScript — mutabile, piena di trappole nel parsing, e inaffidabile quando entrano in gioco i fusi orari. Dopo anni nella pipeline delle proposal di TC39, Temporal è la risposta di JavaScript: una nuova API pensata da zero per lavorare con date, orari e durate, progettata appositamente invece che rattoppata sopra il design originale di Date del 1995.
ℹ️ Nota sulla disponibilità
Temporal è allo Stage 3 di TC39 da tempo, con il supporto nativo che arriva gradualmente nei
motori invece che ovunque in una volta — verifica il supporto attuale di browser/Node prima di
affidartici in produzione, e usa il polyfill ufficiale @js-temporal/polyfill dove non
è ancora disponibile nativamente. Tutto quello che segue descrive l’API come specificata, che è
anche ciò che il polyfill implementa.
Cosa non va davvero in Date
Una lista veloce, perché vale la pena ricordare perché serviva una sostituzione completa invece di correzioni incrementali:
Dateè mutabile.date.setMonth(5)modifica l’oggetto sul posto — passa unDatea una funzione e quella funzione può modificare silenziosamente il tuo valore originale.- Il parsing è incoerente.
new Date("2026-01-15")enew Date("01/15/2026")possono comportarsi diversamente tra motori diversi, e alcuni formati sono decisamente ambigui (01/02/2026è il 2 gennaio o l’1 febbraio?). - La gestione dei fusi orari è aggiunta a posteriori.
Dateinternamente memorizza sempre un timestamp UTC; qualsiasi cosa tu faccia con un fuso orario specifico richiede calcoli manuali sugli offset o una libreria di terze parti comedate-fns-tzo Luxon. - Non esiste un concetto di prima classe per “durata” o “data pura”. Volere “solo una data di calendario senza orario” (un compleanno) o “solo una durata” (45 minuti) significa forzare
Datea rappresentarlo, oppure costruirselo da soli.
I tipi principali di Temporal
Invece di un singolo oggetto che fa tutto, Temporal divide il dominio in tipi distinti e specifici:
| Tipo | Rappresenta |
|---|---|
Temporal.PlainDate |
Una data di calendario senza orario né fuso orario (es. un compleanno) |
Temporal.PlainTime |
Un orario del giorno senza data (es. “l’ufficio apre alle 09:00”) |
Temporal.PlainDateTime |
Una data e un orario senza fuso orario |
Temporal.ZonedDateTime |
Un istante specifico, legato a un fuso orario preciso — quello che di solito serve per “quando è successo” |
Temporal.Instant |
Un punto preciso sulla linea temporale UTC, senza calendario né fuso orario associati |
Temporal.Duration |
Una durata di tempo (es. “2 ore e 30 minuti”) |
// Una data di calendario, nessun orario associato
const birthday = Temporal.PlainDate.from("2026-03-14");
// Un momento specifico, in un fuso orario specifico
const meeting = Temporal.ZonedDateTime.from("2026-09-10T15:00:00[Europe/Rome]");
// Una durata su cui puoi fare aritmetica
const break_ = Temporal.Duration.from({ minutes: 15 });
Ognuno di questi oggetti è immutabile — ogni operazione restituisce una nuova istanza invece di modificare l’originale, lo stesso modello che le alternative moderne più amichevoli a Date (Luxon, date-fns) hanno già reso popolare.
Un esempio pratico: convertire tra fusi orari
Questo è esattamente il tipo di cosa che prima di Temporal richiedeva una libreria:
const meetingInRome = Temporal.ZonedDateTime.from("2026-09-10T15:00:00[Europe/Rome]");
const meetingInNewYork = meetingInRome.withTimeZone("America/New_York");
console.log(meetingInNewYork.toString());
// 2026-09-10T09:00:00-04:00[America/New_York]
Nessun calcolo manuale sugli offset, nessun rischio di dimenticare l’ora legale — withTimeZone gestisce correttamente la conversione, incluse le transizioni DST, perché ZonedDateTime porta con sé l’identificatore di fuso orario IANA (Europe/Rome), non solo un offset UTC numerico.
Aritmetica con le durate
const start = Temporal.PlainDateTime.from("2026-09-10T09:00:00");
const end = start.add({ hours: 2, minutes: 30 });
console.log(end.toString()); // 2026-09-10T11:30:00
const duration = start.until(end);
console.log(duration.toString()); // PT2H30M
add, subtract e until sono disponibili su ogni tipo Temporal per cui ha senso, e gestiscono correttamente i casi limite che l’aritmetica manuale su Date sbaglia spesso — fine mese, anni bisestili, e transizioni DST per ZonedDateTime.
Date vs Temporal a colpo d’occhio
Date |
Temporal | |
|---|---|---|
| Mutabile | Sì | No |
| Data pura senza orario | Non nativamente | Temporal.PlainDate |
| Supporto affidabile ai fusi orari | No (manuale/libreria) | Sì, integrato (ZonedDateTime) |
| Parsing | Incoerente tra motori | Rigoroso, definito dalla spec |
| Durata come tipo di prima classe | No | Temporal.Duration |
| Aritmetica (somma/sottrazione) | Manuale, soggetta a errori | Metodi integrati |
Conviene migrare il codice esistente oggi?
Non in blocco, e non ancora ovunque. Dato il supporto nativo ancora disomogeneo descritto sopra, il percorso pratico per la maggior parte dei progetti nel 2026 è:
- Usare il polyfill per il codice nuovo dove la correttezza di data/ora conta davvero — tutto ciò che gestisce più fusi orari, eventi ricorrenti, o calcoli di calendario.
- Lasciare
Datedov’è quando viene usato solo per loggare un timestamp o misurare il tempo trascorso conDate.now()— non c’è nessun vantaggio di correttezza nel migrarlo. - Tenere d’occhio le tabelle di supporto dei runtime target prima di abbandonare la dipendenza dal polyfill.
FAQ
❓ Temporal sostituisce completamente Date?
Date non viene rimosso dal linguaggio — resta per compatibilità all’indietro. Temporal è la
nuova API consigliata per tutto ciò che va oltre i casi d’uso più semplici di timestamp.
❓ Serve ancora una libreria come Luxon o date-fns se uso Temporal?
Per la maggior parte dei casi d’uso, no — Temporal copre nativamente parsing, aritmetica,
formattazione e conversione di fuso orario. Le librerie costruite attorno al vecchio oggetto
Date diventano in gran parte superflue una volta che Temporal è disponibile nei tuoi ambienti
target.
❓ Posso convertire un Date esistente in Temporal?
Sì — Temporal.Instant.fromEpochMilliseconds(date.getTime()) ti dà un Temporal.Instant a
partire da un Date legacy, che puoi poi convertire in ZonedDateTime con toZonedDateTimeISO()
per un dato fuso orario.
Conclusione
Temporal risolve i problemi strutturali che Date non poteva superare: mutabilità, parsing ambiguo, e gestione dei fusi orari che richiedeva sempre strumenti aggiuntivi. Dividere il dominio in PlainDate, ZonedDateTime, Duration e simili fa sì che il codice che gestisce date correttamente si legga come codice che gestisce date correttamente, invece di nascondere l’intento dietro aritmetica generica su Date. Verifica il supporto dei tuoi runtime target prima di abbandonare il polyfill, ma vale la pena imparare l’API già oggi — è la direzione verso cui sta andando la gestione delle date in JavaScript.
Riferimenti

Co-Fondatore & CTO presso PAPION. Senior full-stack engineer specializzato in React, TypeScript, Node.js e sicurezza applicativa.