Temporal API

L'API Temporal di JavaScript: un sostituto moderno di Date

JavaScript Date è rotto in modi ben noti da decenni. TC39 Temporal — Stage 4 dall'inizio del 2025, già nei browser moderni e in Node.js — separa in modo pulito gli istanti, le date da orologio da parete e le date-ora con fuso. Questa guida spiega i nuovi tipi, come si rapportano ai timestamp Unix e come migrare.

Temporal vs Date a colpo d'occhio

Il Date integrato di JavaScript è una fonte nota di bug da decenni: è mutabile, capisce solo il fuso locale e UTC, i suoi mesi sono indicizzati da zero e il suo parsing è specificato in modo lasco. Temporal è il sostituto normalizzato — Stage 4 e parte di ECMAScript 2026 — e corregge ognuno di quei problemi con tipi immutabili costruiti su misura. La tabella sotto è il contrasto generale; il resto di questa guida copre i tipi e come si rapportano ai timestamp Unix.

AspettoDate (legacy)Temporal
MutabilitàMutabileImmutabile
PrecisioneMillisecondiNanosecondi
Fusi orariSolo locale + UTCQualsiasi fuso IANA (ZonedDateTime)
Indicizzazione dei mesiBase 0 (0 = gennaio)Base 1 (1 = gennaio)
ParsingPermissivo, definito dall'implementazioneISO 8601 / RFC 9557 rigoroso
Istante vs orologio da pareteConfusi in un unico tipoTipi separati

Perché esiste Temporal

JavaScript Date confonde diversi concetti distinti: un istante esatto, un'ora da orologio da parete e una data-ora con fuso. Date ha anche peculiarità di parsing ben note, un unico fuso (quello dell'utente) e precisione al millisecondo. Temporal espone i concetti sottostanti come tipi separati e supporta precisione al nanosecondo, fusi IANA arbitrari e sistemi di calendario espliciti.

  • Stage 4 dall'inizio del 2025; rilasciato per primo per impostazione predefinita in Firefox 139
  • Ora disponibile in Chrome 144+, Firefox 139+ e Node.js 26+
  • I polyfill (@js-temporal/polyfill) funzionano in qualsiasi ambiente moderno
  • Progettato per coesistere con Date — esistono metodi di interoperabilità in entrambe le direzioni

I tipi essenziali di Temporal

Un piccolo insieme di tipi copre in modo pulito il problema delle date-ora. Ciascuno ha una forma di stringa canonica (ISO 8601, estesa dalla RFC 9557 per il tipo con fuso):

TipoRappresentaStringa di esempio
Temporal.InstantUn istante esatto, come un timestamp Unix (precisione ns)2026-01-01T00:00:00Z
Temporal.ZonedDateTimeIstante + fuso IANA + calendario2026-01-01T09:00:00+09:00[Asia/Tokyo]
Temporal.PlainDateTimeData + ora, senza fuso2026-01-01T09:00:00
Temporal.PlainDateUna data di calendario (es. un compleanno)2026-01-01
Temporal.PlainTimeUn'ora da orologio da parete09:00:00
Temporal.DurationUna durata, consapevole delle unitàP3DT4H10M

Lavorare con i timestamp Unix

Temporal.Instant è il tipo timestamp Unix. L'API rilasciata espone solo conversioni epoch in millisecondi e nanosecondi — i metodi precedenti fromEpochSeconds e fromEpochMicroseconds sono stati rimossi prima dello Stage 4 — quindi converti i secondi Unix moltiplicando per 1000. Usa Instant per archiviazione e trasporto, e ZonedDateTime quando ti serve una vista da orologio da parete in un fuso specifico.

  • Temporal.Now.instant() — il momento esatto attuale
  • Temporal.Instant.fromEpochMilliseconds(Date.now()) — da un timestamp JS in millisecondi
  • Temporal.Instant.fromEpochMilliseconds(1700000000 * 1000) — da secondi Unix (× 1000)
  • Temporal.Instant.fromEpochNanoseconds(1700000000000000000n) — da nanosecondi (BigInt)
  • instant.epochMilliseconds e instant.epochNanoseconds — rileggere il valore epoch
  • instant.toZonedDateTimeISO("America/New_York") — una vista da orologio da parete in un fuso

Fusi e DST gestiti correttamente

ZonedDateTime porta un fuso IANA, quindi le transizioni di DST, le ore di buco e le ore di sovrapposizione sono tutte gestite esplicitamente. L'opzione di disambiguazione ti lascia scegliere una politica per le ore locali ambigue, e il formato di stringa canonico è la RFC 9557 (un timestamp ISO 8601 con il fuso tra parentesi quadre).

  • zdt.timeZoneId — il nome IANA (es. America/Los_Angeles)
  • zdt.add({ hours: 1 }) — aritmetica consapevole del DST in termini di orologio da parete
  • zdt.until(zdt2) — distanza tra due date-ora con fuso
  • Opzioni di disambiguazione: "earlier", "later", "compatible" (predefinito — successivo per il buco, precedente per la sovrapposizione), "reject"
  • Andata e ritorno: istante ↔ data-ora con fuso è senza perdite

Schemi di migrazione da Date

La strategia di migrazione più semplice è introdurre Temporal prima ai confini (parsing dell'input, formattazione dell'output) e spostare gradualmente la logica interna.

  • Date → Instant: Temporal.Instant.fromEpochMilliseconds(date.getTime())
  • Instant → Date: new Date(instant.epochMilliseconds)
  • Per il codice nuovo, preferisci Temporal ovunque e converti in Date solo ai bordi dell'API
  • date-fns e Luxon hanno entrambi modalità / adattatori consapevoli di Temporal
  • JSON: Temporal.Instant.prototype.toJSON restituisce una stringa ISO 8601

Supporto in browser e runtime

Temporal è stato rilasciato nel 2025 e il supporto nativo è ormai ampio, ma non ancora universale. Il polyfill è la via più sicura finché i browser più vecchi e Safari stabile sono ancora in uso.

  • Firefox 139+: il primo a rilasciarlo, abilitato per impostazione predefinita (maggio 2025)
  • Chrome 144+: abilitato per impostazione predefinita (gennaio 2026)
  • Node.js 26+: abilitato per impostazione predefinita (maggio 2026)
  • Safari: disponibile in Technology Preview, non ancora in una versione stabile
  • Polyfill: @js-temporal/polyfill o temporal-polyfill — stessa API, qualsiasi ambiente moderno

Riferimenti correlati

FAQ

Temporal è un sostituto di Date?
Sì — Temporal è progettato per sostituire del tutto Date nel codice nuovo. Date rimane nel linguaggio per retrocompatibilità, e i due interoperano tramite i millisecondi epoch.
Come converto un timestamp Unix in Temporal?
Usa Temporal.Instant.fromEpochMilliseconds(). Per i secondi Unix, moltiplica per 1000: Temporal.Instant.fromEpochMilliseconds(seconds * 1000). L'API rilasciata ha solo fromEpochMilliseconds e fromEpochNanoseconds — il vecchio metodo fromEpochSeconds è stato rimosso prima che Temporal raggiungesse lo Stage 4.
Temporal supporta i nanosecondi?
Sì. Temporal.Instant ha precisione al nanosecondo internamente ed espone epochNanoseconds come un BigInt.
Posso usare Temporal in Node.js oggi?
In Node.js 26+ Temporal è abilitato per impostazione predefinita. Nelle versioni precedenti di Node, installa @js-temporal/polyfill — la superficie dell'API è identica.
Quali browser supportano Temporal?
Firefox 139+ (maggio 2025), Chrome 144+ (gennaio 2026) e Node.js 26+ (maggio 2026) includono Temporal per impostazione predefinita. Safari lo ha in Technology Preview. Per qualsiasi cosa più vecchia, usa il @js-temporal/polyfill.
Come gestisce Temporal il buco del DST?
I costruttori e l'aritmetica di ZonedDateTime accettano un'opzione di disambiguazione. "compatible" (predefinito) sceglie l'istante successivo per i buchi e quello precedente per le sovrapposizioni; "reject" lancia un errore se l'ora locale è ambigua.