Scrivere una data in ISO 8601, e perché è l'unico formato non ambiguo
Pubblicato il 13/08/2026 · 16 min di lettura · Strumenti testo e lingua
Daniel Okonkwo — Sviluppatore front-end e redattore Tech presso OneKitly
Performance web · Formati di file
Verificato su 4 fonti
Scrivi prima l'anno, poi il mese, poi il giorno, ciascuno con gli zeri iniziali: 2026-02-01. L'ordine è tutto il trucco. Poiché i campi vanno dall'unità più grande alla più piccola e ognuno ha larghezza fissa, confrontare due stringhe carattere per carattere dà la stessa risposta del confronto fra i due istanti — ed è per questo che ordinare una cartella di file così nominati li mette in ordine cronologico senza alcuna logica di date. L'ora si unisce alla data con una T maiuscola, e si aggiunge un offset rispetto a UTC: 2026-02-01T09:30:00+01:00, oppure Z quando l'offset è zero. Una data-ora senza offset è una data locale il cui senso dipende da dove viene letta, esattamente l'ambiguità che il formato esiste per togliere, quindi aggiungi l'offset a meno che tu non intenda davvero un orologio da parete. Lo strumento è stato provato su questo: tiene un istante come sette interi e converte con aritmetica intera anziché con un oggetto Date, così 2026-08-13T00:30:00+02:00 torna come 2026-08-12T22:30:00Z, un giorno prima e corretto, con un timestamp Unix di 1786573800 identico a Date.UTC. Il suo pulsante «Adesso» legge l'orologio in UTC, quindi subito dopo mezzanotte a Parigi precompila la data del giorno prima: sorprendente, non sbagliato. Due avvertenze. L'ordinamento testuale equivale a quello temporale solo se tutte le stringhe portano lo stesso offset; mescola Z e +02:00 e l'ordine è sbagliato in silenzio. E ISO 8601 è più ampio della RFC 3339, che è ciò che la maggior parte delle API richiede davvero: una data nuda, una data di settimana, una stringa in formato base e un'ora 24 sono tutte ISO 8601 valido e nessuna è RFC 3339 valido.
01/02/2026 è il 1º febbraio in gran parte d'Europa e il 2 gennaio negli Stati Uniti, e nulla nella stringa dice quale. ISO 8601 risolve la cosa, si ordina come testo, e smette di bastare in quattro punti precisi che la RFC 3339 rifiuta.
01/02/2026 e le sei lingue in cui questo sito è scritto
Un lettore a Parigi, Madrid, Lisbona, Berlino o Roma legge 01/02/2026 come il 1º febbraio. Un lettore negli Stati Uniti legge le stesse otto cifre come il 2 gennaio. Nulla nella stringa decide fra i due: entrambe le letture sono complete, entrambe sono convenzionali, ed entrambe sbagliano circa una volta su due appena la stringa ha viaggiato.
Il guasto è silenzioso, ed è questo a renderlo caro. Un modulo accetta la data, un database la salva, un report la stampa, e nulla protesta fino al dodicesimo giorno del mese, quando le due letture smettono di produrre ciascuna una data valida e una finisce per sollevare un errore. Tutto quello che stava fra il 1º e il 12 è stato spostato in silenzio. Una consegna prevista per il 3 aprile arriva il 4 marzo, una fattura è datata undici mesi prima, e la traccia di controllo registra entrambe come scritture perfettamente ordinarie.
2026-02-01 non ha una seconda lettura. L'anno viene per primo perché è l'unità più grande, il mese poi, il giorno per ultimo, e ciascuno è riempito a larghezza fissa. Nessun locale da consultare, nessuna convenzione di separatore da indovinare, nessun mese che possa passare per giorno. È tutto il contributo della norma, e basta.
Ordinare come testo e ordinare nel tempo sono la stessa operazione
Ordina i campi dal più grande al più piccolo, riempi ciascuno a larghezza fissa, e il confronto lessicografico diventa gratis un confronto cronologico. Cinque istanti sono stati passati nello strumento, ordinati una volta come stringhe e una volta per i loro timestamp Unix: i due ordini erano identici. È questa proprietà a far sì che una cartella di file chiamati 2026-02-01-note.md, 2026-02-11-note.md e 2026-10-02-note.md stia nell'ordine giusto in qualsiasi gestore di file, qualsiasi shell e qualsiasi elenco di backup, senza alcuna analisi di date in tutta la catena.
La proprietà ha una condizione facile da perdere: ogni stringa deve portare lo stesso offset. Due istanti lo mostrano. 2026-01-05T09:00:00Z e 2026-01-05T10:00:00+02:00 si ordinano in quest'ordine come testo, perché il carattere 9 precede il carattere 1 seguito da 0. I loro timestamp Unix sono 1767603600 e 1767600000, quindi il secondo è avvenuto per primo. L'ordine testuale è sbagliato e nulla lo segnala. Se una colonna può contenere offset misti, normalizza tutto a Z prima di ordinare, oppure ordina sul timestamp.
Lo stesso ragionamento spiega la convenzione dei nomi di file. Metti la data all'inizio del nome e la cartella si ordina da sola; mettila alla fine e si ordina per ciò che la precede. Usa trattini e non barre, perché la barra è un separatore di percorso su ogni sistema, e i due punti — leciti in un'ora ma vietati in un nome di file su Windows — spiegano perché un nome con data e ora di solito ripiega su 2026-02-01T093000Z, il formato base che la norma definisce anch'essa.
La T, la Z e un offset che non è un fuso orario
La T maiuscola unisce la data all'ora. È lì perché una data e un'ora sono due rappresentazioni distinte e qualcosa deve dire dove finisce l'una e comincia l'altra; per una persona basterebbe uno spazio, ed è esattamente ciò che stampa un database, ma la norma stretta vuole la T. La Z finale significa offset zero — Zulu, dall'alfabeto fonetico militare — ed è intercambiabile con +00:00.
Un offset come +02:00 dice quanto l'orologio da parete si scosta da UTC in quell'istante, e nulla di più. Non nomina Parigi: nello stesso momento è anche Il Cairo, Johannesburg, Helsinki e mezza Europa, e lo stesso orologio parigino a gennaio è a +01:00. Ecco perché un appuntamento futuro va salvato come identificatore di fuso — Europe/Paris — con l'ora locale, e non come offset. Salva 2027-03-28T10:00:00+01:00 per una riunione e sarà alle nove del mattino dopo il cambio dell'ora, cosa che nessuno ha concordato.
Una data-ora senza alcun offset è una data locale, e il suo senso è quello che decide la macchina di chi legge. È ISO 8601 valido ed è a volte ciò che si vuole — un negozio apre alle 09:00 nella città in cui si trova — ma non è un istante, e trattarlo come tale è il modo in cui una riga di log da un server all'estero arriva all'ora sbagliata e una data di nascita in un database diventa il giorno prima per chiunque sia a ovest del meridiano.
A caccia dello scarto di un giorno attorno a mezzanotte, senza trovarlo
Il difetto più comune negli strumenti per le date è una conversione che passa dal fuso locale del browser e finisce un giorno più in là vicino a mezzanotte. Questo non ce l'ha, per una ragione strutturale: non tocca mai l'ora locale. Un istante è conservato come sette interi — anno, mese, giorno, ora, minuto, secondo e offset in minuti — e la conversione verso UTC sposta il numero del giorno con aritmetica intera anziché costruire un Date. Il pulsante «Adesso» legge l'orologio con getUTCFullYear e sorelle e fissa l'offset a UTC+00:00.
I casi limite sono stati eseguiti apposta. Parigi alle 00:30 del 13 agosto con offset +02:00 dà una forma UTC 2026-08-12T22:30:00Z e una data HTTP Wed, 12 Aug 2026 22:30:00 GMT — un giorno prima, il che è corretto, perché è lo stesso istante. New York alle 23:30 del 12 agosto con offset −04:00 va nel senso opposto, verso 2026-08-13T03:30:00Z. Le isole Chatham alle 00:10 del 1º gennaio con offset +12:45 escono come 2025-12-31T11:25:00Z, attraversando insieme un giorno e un anno. Cinque di questi casi sono stati confrontati con Date.UTC, compreso il 1969-07-20T20:17:40Z antecedente all'epoca, il cui timestamp di −14 182 940 ha coinciso esattamente.
L'unica cosa che sembra uno scarto di un giorno è il pulsante «Adesso», ed è una scelta deliberata che traspare. Poiché l'orologio è letto in UTC, un lettore parigino che lo prema a mezzanotte e mezza del 13 agosto vede il campo data precompilato col 12 agosto e l'ora con 22:30. È lo stesso momento espresso nel fuso predefinito dello strumento, non la data di ieri. Se vuoi il tuo orologio da parete, inserisci data e ora a mano e scegli il tuo offset dall'elenco.
La RFC 3339 è ciò che intende la tua API, ed è più stretta
Quando un'API dice di volere ISO 8601, quasi sempre vuole RFC 3339, che si descrive da sé come un profilo di ISO 8601 per l'uso su Internet. Un profilo è un sottoinsieme: tutto ciò che la RFC 3339 accetta è ISO 8601, e buona parte di ISO 8601 non è RFC 3339. La sua grammatica esige una data completa, poi una T, poi un'ora completa, poi un offset — nulla può essere omesso.
Quattro differenze contano nella pratica, tutte leggibili nella grammatica stessa della RFC. La sua ora è definita come due cifre da 00 a 23, quindi 24:00 — fine giornata lecita in ISO, che indica lo stesso istante della mezzanotte del giorno dopo — non è RFC 3339. Il suo offset si scrive segno, due cifre, due punti e altre due cifre: +0200 e +02 sono ISO 8601 e nessuno dei due è RFC 3339. Non ha date di settimana né date ordinali, quindi 2026-W33-4 e 2026-225 ne restano fuori. E una data nuda come 2026-08-13, o un anno con un mese, o un anno da solo, secondo la RFC 3339 non è affatto una data-ora.
Due sottigliezze vanno nel senso opposto, dove la RFC 3339 è più permissiva. Dà a −00:00 un significato proprio: l'ora UTC è nota ma l'offset locale no, cosa deliberatamente diversa da Z o da +00:00. E una nota della stessa sezione dice che le applicazioni possono usare uno spazio al posto della T per leggibilità, che è esattamente ciò che stampano i database. Lo strumento accetta uno spazio incollato e ti avvisa di averlo visto; accetta anche −00:00 e lo trasforma in silenzio in Z, sicché la distinzione tracciata dalla RFC non sopravvive a un andata e ritorno.
Una conseguenza merita di essere segnalata, perché lo strumento non lo fa. Il suo campo di uscita principale, quello etichettato come forma estesa di data e ora, è RFC 3339 finché l'ora sta fra 00 e 23 — e non lo è quando l'ora vale 24, cosa che l'analizzatore accetta. Incolla 2026-08-13T24:00:00Z e quel campo te lo restituisce tale e quale, e il campo etichettato come data e-mail stampa un'ora che nemmeno la RFC 5322 consente. La riga UTC accanto è giusta: indica 2026-08-14T00:00:00Z. Se stai copiando un valore verso un'API, copia quello.
Date di settimana, date ordinali e le piccole cose che lo strumento sbaglia
ISO 8601 definisce altre due forme di data e lo strumento le stampa entrambe. Una data di settimana nomina l'anno, la settimana e il giorno della settimana, e il suo anno non è sempre l'anno civile: una settimana appartiene all'anno che contiene il suo giovedì. Passa il 1º gennaio 2027 nello strumento e torna come 2026-W53-5; passa il 31 dicembre 2024 e torna come 2025-W01-2. Entrambi sono stati verificati. Una data ordinale nomina l'anno e il giorno al suo interno, quindi il 13 agosto 2026 è 2026-225. Entrambe si ordinano lessicograficamente bene quanto le date civili — ma non mescolare mai le tre forme in una stessa colonna, perché 2026-W33-4 e 2026-08-13 si ordinano fra loro come stringhe, senza alcun rapporto col tempo.
Tre piccoli difetti sono emersi nelle prove e vale la pena conoscerli più che temerli. Un secondo pari a 60 è accettato ovunque — incolla 2026-08-13T00:30:60Z e lo strumento lo prende e calcola un timestamp Unix di 1786581060, cioè le 00:31:00 — mentre sia la norma sia la RFC ammettono il 60 solo sotto le regole del secondo intercalare. Le frazioni di secondo sono lette e poi buttate: 2026-08-13T00:30:00.123Z torna come 2026-08-13T00:30:00Z, senza alcun avviso che i millisecondi sono spariti. E l'analizzatore di durate rifiuta P0D, una durata zero perfettamente lecita, perché scarta ogni durata i cui campi siano tutti zero.
Ciò che fa bene merita la stessa frase. Rifiuta 2026-02-30 e 2026-08-13T25:00:00Z, rifiuta un 2026-8-3 non riempito, e rifiuta seccamente 13/08/2026 e 08/13/2026, che è la risposta giusta per uno strumento il cui compito è dire cosa è e cosa non è ISO 8601. Legge il formato base 20260813T003000+0200, legge una t e una z minuscole, e ti dice quale delle tre forme di data ha riconosciuto. Anche le durate vengono analizzate correttamente, compresa la virgola decimale di P1,5D, che normalizza in P1.5D.
| Stringa | Stato | Perché |
|---|---|---|
| 2026-08-13T00:30:00+02:00 | Entrambe | Data completa, T, ora completa, offset con i due punti — esattamente la grammatica RFC 3339 |
| 2026-08-13 | Solo ISO 8601 | La RFC 3339 definisce una data-ora, non una data da sola |
| 2026-W33-4T12:00:00+02:00 | Solo ISO 8601 | Le date di settimana non sono nella grammatica RFC 3339; lo strumento la legge come 13 agosto 2026 |
| 20260813T003000+0200 | Solo ISO 8601 | Il formato base toglie i separatori; la RFC 3339 li esige |
| 2026-08-13T24:00:00Z | Solo ISO 8601 — e lo strumento lo ristampa | La RFC 3339 fissa l'ora da 00 a 23; la riga UTC mostra correttamente 2026-08-14T00:00:00Z |
| 2026-08-13 00:30:00Z, con uno spazio | RFC 3339 per una nota; lo strumento lo accetta e lo segnala | Una nota della sezione 5.6 ammette uno spazio per leggibilità; la norma stretta vuole la T |
| 2026-08-13T00:30:00-00:00 | Solo RFC 3339; lo strumento lo trasforma in Z | La sezione 4.3 gli dà il senso «offset sconosciuto», che la conversione cancella |
| 2026-08-13T00:30:60Z | Nessuna delle due, e lo strumento lo accetta | Un secondo pari a 60 è un secondo intercalare, solo alle 23:59:60; il timestamp esce come 00:31:00 |
| 13/08/2026 e 08/13/2026 | Nessuna delle due; lo strumento le rifiuta entrambe | L'ambiguità che l'intera norma esiste per togliere — rifiutare è la risposta giusta |
Domande frequenti
- Devo scrivere l'offset o usare Z ovunque?
- Per tutto ciò che salvi, registri o invii fra macchine, normalizza a Z. Ogni valore porta allora lo stesso offset, quindi l'ordinamento testuale equivale a quello temporale, i confronti non richiedono conversione e non c'è nulla da sbagliare. Tieni l'offset locale solo quando la lettura locale è essa stessa il fatto: una ricevuta che deve dire che la transazione è avvenuta alle 09:15 nella mattinata del negozio, una partenza di treno stampata per i passeggeri. E per un appuntamento futuro nessuno dei due va bene: salva l'identificatore di fuso e l'ora locale, perché l'offset che quel fuso avrà in quella data è una decisione che nessuno ha ancora preso.
- ISO 8601 e RFC 3339 sono la stessa cosa?
- No. La RFC 3339 si presenta come un profilo di ISO 8601 per i protocolli Internet, e un profilo è un sottoinsieme. La sua grammatica ammette solo la data di calendario, esige la presenza dell'ora e dell'offset, limita l'ora da 00 a 23, e scrive l'offset con due punti e minuti obbligatori. Quindi una data nuda, una data di settimana come 2026-W33-4, una data ordinale come 2026-225, il formato base senza trattini, un'ora di 24 e un offset scritto +0200 o +02 sono tutti ISO 8601 valido e nessuno è RFC 3339 valido. Nel senso opposto, la RFC 3339 dà a -00:00 un significato proprio — l'ora UTC è nota ma l'offset locale no — e ammette t e z minuscoli. Quando un'API chiede ISO 8601, manda RFC 3339 e soddisferai entrambe.
- Perché lo strumento mostra la data di ieri quando premo «Adesso»?
- Perché legge l'orologio in UTC e fissa l'offset a UTC+00:00, non perché abbia contato male. Se sei a est di Greenwich ed è poco dopo mezzanotte, il tuo orologio da parete è già nel giorno nuovo mentre UTC è ancora in quello vecchio. Un lettore parigino che prema «Adesso» alle 00:30 del 13 agosto vede compilati 12 agosto e 22:30 — lo stesso momento, espresso nel fuso predefinito dello strumento. Nulla della conversione passa dal fuso della tua macchina: l'istante è tenuto come interi e spostato con aritmetica intera, e cinque casi limite, fra cui una data antecedente all'epoca e un offset di +12:45, hanno coinciso esattamente con Date.UTC. Se vuoi la tua ora da parete, digita data e ora e scegli il tuo offset dall'elenco.
- Posso davvero ordinare le date ordinando il testo?
- Sì, a una condizione: ogni stringa deve avere la stessa forma e lo stesso offset. Cinque istanti sono stati ordinati in entrambi i modi nello strumento e gli ordini erano identici. Rompi la condizione e fallisce in silenzio: 2026-01-05T09:00:00Z si ordina prima di 2026-01-05T10:00:00+02:00 come testo, ma i loro timestamp sono 1767603600 e 1767600000, quindi quello che va secondo è avvenuto per primo. Mescolare date civili e date di settimana lo rompe altrettanto, perché 2026-W33-4 si confronta con 2026-08-13 come due stringhe senza significato comune. Normalizza a Z e a una sola forma prima di ordinare, e il trucco è del tutto sicuro — che è esattamente il motivo per cui è il modo giusto di nominare i file.
- Perché il 1º gennaio 2027 si scrive 2026-W53-5?
- Perché una settimana appartiene per intero a un solo anno, e la norma la assegna a quello che contiene il suo giovedì. La settimana che comprende il 1º gennaio 2027 ha il suo giovedì il 31 dicembre 2026, quindi l'intera settimana è la settimana 53 dell'anno di numerazione 2026, e il venerdì che contiene è il giorno 5. La stessa regola vale al contrario: il 31 dicembre 2024 esce come 2025-W01-2, entrambi verificati nello strumento. Due conseguenze pratiche. L'anno di numerazione delle settimane non è l'anno civile e non va mai accostato a un mese civile in un titolo di report. E un anno ha 53 settimane quando il suo 1º gennaio cade di giovedì, o di mercoledì in un anno bisestile — il 2026 ne ha 53, il 2027 ne ha 52 — sicché un grafico con 52 colonne fisse sposta una settimana circa ogni cinque o sei anni.
Articoli che potrebbero interessarti
Tutte le guide →Strumenti correlati
Tutto quanto segue descrive ciò che questi quattro strumenti fanno oggi, verificato eseguendo il loro stesso codice sugli input esatti riportati in ogni articolo, e non ciò che una norma imponga loro. Dove uno strumento sbaglia un caso, la cosa è scritta chiaramente anziché aggirata, e nulla è stato modificato perché un articolo si leggesse meglio. Due conseguenze. Esegui ogni trasformazione prima su una copia e confronta i due estremi: uno strumento di testo che cancella qualcosa non lo dice. E considera condiviso un segreto dal momento in cui lascia la pagina: incollarlo in una chat, in un ticket o in un repository lo brucia, per quanto bene sia stato generato.
Fonti
- IETF — RFC 3339 — Date and Time on the Internet: Timestamps (§5.6 grammar, §4.3 unknown local offset)
- IETF — RFC 9557 — Timestamps with Additional Information, which extends RFC 3339 with a zone identifier
- WHATWG — HTML Standard — dates and times: the date, time and datetime microsyntaxes browsers accept
- MDN Web Docs — Date.prototype.toISOString() — the simplified extended format JavaScript emits
Hai notato un errore in questo articolo?