Il tempo sembra semplice finché non provi a scrivere del software che lo gestisca correttamente. Un evento programmato per le "15:00" significa cose diverse a Tokyo, Londra e New York. L'ora legale sposta gli orologi avanti o indietro — ma non ovunque e non nelle stesse date. Un timestamp che sembra corretto nel tuo ambiente locale si rompe in produzione perché il server si trova in un fuso orario diverso.
I fusi orari sono uno degli argomenti più regolarmente confusi nello sviluppo software. Questo articolo spiega come funzionano, da dove viene la complessità e come evitare gli errori più comuni.
Perché esistono i fusi orari
La Terra ruota di 360 gradi in 24 ore, il che significa che il sole è al punto più alto in momenti diversi a seconda della longitudine. Prima del XIX secolo, ogni città impostava i propri orologi sull'ora solare locale — mezzogiorno era quando il sole era allo zenit. Questo funzionava bene finché le ferrovie non collegarono città distanti e gli orari dei treni ebbero bisogno di un orologio unico e coerente.
Nel 1884, i delegati di 25 nazioni si riunirono alla Conferenza Internazionale del Meridiano a Washington, D.C. e concordarono di dividere il mondo in 24 fusi orari standard, ciascuno con un offset dal primo meridiano (0 gradi di longitudine) che passa per Greenwich, in Inghilterra.
In pratica, i confini dei fusi orari seguono i confini politici, non linee longitudinali ordinate. La Cina si estende su cinque zone geografiche ma usa un unico orario ufficiale (UTC+8). L'India usa UTC+5:30 — un offset di mezz'ora. Il Nepal usa UTC+5:45. La mappa reale dei fusi orari è caotica.
UTC vs. GMT
GMT (Greenwich Mean Time) è l'ora solare media all'Osservatorio Reale di Greenwich. È stato il riferimento temporale mondiale per oltre un secolo.
UTC (Coordinated Universal Time) ha sostituito il GMT come standard internazionale nel 1972. UTC si basa su orologi atomici piuttosto che sull'osservazione astronomica, rendendolo molto più preciso. Per la maggior parte degli scopi pratici, UTC e GMT mostrano la stessa ora, ma UTC è il riferimento tecnico corretto.
Perché "UTC" e non "CUT"? L'abbreviazione è un compromesso tra l'inglese "Coordinated Universal Time" (CUT) e il francese "Temps Universel Coordonné" (TUC). Nessuna delle due parti ottenne il proprio acronimo preferito, quindi fu scelto UTC come alternativa linguisticamente neutrale.
Ora legale: caos organizzato
Circa 70 paesi osservano l'ora legale (DST), spostando gli orologi avanti di un'ora in primavera e indietro in autunno. L'intento è allineare le ore di veglia con la luce del giorno. Il risultato è una fonte semestrale di bug.
Complicazioni principali:
- Non universale. La maggior parte dell'Africa, dell'Asia e del Sud America non osserva l'ora legale. Negli Stati Uniti, l'Arizona e le Hawaii non partecipano.
- Date diverse. L'UE cambia l'ultima domenica di marzo e ottobre. Gli USA cambiano la seconda domenica di marzo e la prima domenica di novembre. Non sono sincronizzati per diverse settimane ogni anno.
- Orari ambigui. Quando gli orologi tornano indietro, l'ora dall'1:00 alle 2:00 si verifica due volte. Un timestamp "1:30" in quel giorno è ambiguo.
- Orari saltati. Quando gli orologi vanno avanti, l'ora dalle 2:00 alle 3:00 non esiste. Una riunione programmata alle 2:30 di quel giorno non si verifica mai.
- Cambiamenti politici. I governi possono (e lo fanno) cambiare le regole dell'ora legale con poco preavviso. La Russia ha adottato l'ora legale permanente nel 2011, poi è passata all'ora solare permanente nel 2014. Il Marocco ha cambiato le regole dell'ora legale più volte.
ISO 8601: il formato data universale
Per evitare ambiguità, lo standard internazionale ISO 8601 definisce un formato chiaro per data e ora:
2026-03-29T14:30:00Z
2026-03-29T14:30:00+02:00
2026-03-29T14:30:00-05:00
- Il
Tsepara la data dall'ora. Zsignifica UTC (il fuso orario "Zulu" nella terminologia militare).+02:00o-05:00è l'offset UTC.
Questo formato è non ambiguo, ordinabile come testo semplice e universalmente compreso dalle librerie di parsing delle date. In caso di dubbio, usa ISO 8601.
Timestamp Unix
Un timestamp Unix (chiamato anche tempo epoch o tempo POSIX) è il numero di secondi trascorsi dal 1 gennaio 1970, 00:00:00 UTC — un momento noto come l'epoch Unix.
| Leggibile | Timestamp Unix |
|---|---|
| 1970-01-01 00:00:00 UTC | 0 |
| 2000-01-01 00:00:00 UTC | 946684800 |
| 2026-03-29 12:00:00 UTC | 1774987200 |
I timestamp Unix non hanno fuso orario — sono sempre in UTC. Questo li rende ideali per memorizzare e confrontare orari nel software. Si converte nel fuso orario locale solo al livello di visualizzazione.
Il problema dell'anno 2038: I sistemi che memorizzano i timestamp Unix come intero con segno a 32 bit andranno in overflow il 19 gennaio 2038 alle 03:14:07 UTC. Il valore massimo (2.147.483.647) passerà a un numero negativo, interpretato come dicembre 1901. La maggior parte dei sistemi moderni usa interi a 64 bit, che non andranno in overflow per altri 292 miliardi di anni.
Il database dei fusi orari IANA
Il software non ha bisogno solo degli offset UTC — ha bisogno di conoscere la storia completa e le regole future per ogni regione, incluse le transizioni dell'ora legale, i cambiamenti politici e le anomalie storiche. Queste informazioni risiedono nel Database dei fusi orari IANA (chiamato anche database Olson o tzdata).
Usa identificatori come America/New_York, Europe/Paris, Asia/Tokyo. Ogni voce codifica la storia completa degli offset UTC e delle regole dell'ora legale per quella località.
Ecco perché non dovresti mai memorizzare un fuso orario come offset fisso come "+02:00". Un offset ti dice la differenza attuale da UTC ma non dice nulla sulle regole dell'ora legale. Europe/Paris è UTC+1 in inverno e UTC+2 in estate. L'identificatore IANA cattura entrambi.
Bug comuni nel software
- Memorizzare l'ora locale senza fuso orario. Un valore come
2026-03-29 14:30:00non ha significato senza sapere a quale fuso orario si riferisce. Memorizza sempre UTC o includi l'offset. - Assumere che l'offset UTC equivalga al fuso orario. UTC+2 a marzo potrebbe essere UTC+3 a luglio (se la regione osserva l'ora legale). Memorizza l'identificatore IANA, non l'offset.
- Ignorare le transizioni dell'ora legale nella pianificazione. Un job giornaliero alle 2:30 verrà saltato una volta l'anno e eseguito due volte una volta l'anno se non gestisci l'ora legale.
- Assumere che i giorni abbiano 24 ore. Nei giorni di transizione dell'ora legale, un giorno ha 23 o 25 ore. Calcolare "domani alla stessa ora" aggiungendo 86.400 secondi sarà sbagliato di un'ora.
- Usare
Datedi JavaScript in modo ingenuo.new Date("2026-03-29")viene interpretato come UTC in alcuni motori e come ora locale in altri. Sii sempre esplicito riguardo al fuso orario.
Buone pratiche per gli sviluppatori
- Memorizza i tempi in UTC. Converti nel fuso orario locale dell'utente solo al livello di presentazione.
- Usa gli identificatori IANA dei fusi orari (
America/New_York), non offset fissi (-05:00). - Usa ISO 8601 per la serializzazione. È non ambiguo e universalmente analizzabile.
- Usa una libreria date matura. In JavaScript, usa
Intl.DateTimeFormato una libreria comedate-fns-tz. In Python, usazoneinfo(3.9+) opytz. In Java, usajava.time.ZonedDateTime. - Mantieni
tzdataaggiornato. I governi cambiano le regole dell'ora legale. Il tuo sistema operativo e il runtime del linguaggio hanno bisogno di dati sui fusi orari aggiornati. - Testa con più fusi orari. Non assumere che il tuo server e i tuoi utenti condividano lo stesso fuso.
Per approfondire
Il tempo è ingannevolmente complesso, ma le regole sono ben documentate e gli strumenti sono maturi. La chiave è rispettare la complessità anziché ignorarla.
- Espressioni Cron demistificate — pianificare task attraverso i fusi orari
- Generatore di hash e Tester regex — altri strumenti per sviluppatori su ToolK
