Best practice per l'ora legale e il fuso orario [chiuso]


2046

Spero di fare di questa domanda e delle sue risposte la guida definitiva alla gestione dell'ora legale, in particolare alla gestione degli attuali cambi.

Se hai qualcosa da aggiungere, per favore fallo

Molti sistemi dipendono dal mantenimento dell'ora esatta, il problema è con le modifiche all'ora dovute all'ora legale: spostare l'orologio in avanti o indietro.

Ad esempio, in un sistema di acquisizione ordini si hanno regole aziendali che dipendono dall'ora dell'ordine: se l'orologio cambia, le regole potrebbero non essere così chiare. Come dovrebbe essere mantenuto il tempo dell'ordine? Esistono ovviamente un numero infinito di scenari: questo è semplicemente illustrativo.

  • Come hai affrontato il problema dell'ora legale?
  • Quali ipotesi fanno parte della tua soluzione? (cercando il contesto qui)

È importante, se non di più:

  • Cosa hai provato che non ha funzionato?
  • Perché non ha funzionato?

Sarei interessato alla programmazione, al sistema operativo, alla persistenza dei dati e ad altri aspetti pertinenti della questione.

Le risposte generali sono ottime, ma vorrei anche vedere i dettagli soprattutto se sono disponibili solo su una piattaforma.


2
@abatishchev - In questo modo GETDATE()su SQL sarà UTC (come lo sarà DateTime.Now). E il server non verrà influenzato da alcun tipo di modifica automatica dell'ora legale.
Oded,

4
@Oded: posso essere d'accordo se verrà aggiunto "on server". Tuttavia, ciò può influire su altre applicazioni che richiedono l'ora locale. Con questo e altri motivi penso sia meglio richiedere il tempo Utc in modo esplicito.
abatishchev,

7
L'ora UTC è preferita al GMT, sia perché è definita più precisamente sia perché le definizioni GMT sono incasinate su alcuni sistemi operativi. È comune per le persone trattare i termini "GMT" e "UTC" come intercambiabili, ma non sono del tutto. Per quasi tutti gli scopi di software / sistemi, utilizzare UTC. Vedi stackoverflow.com/questions/2292334/…
Chris Johnson,

7
@JoshStodola - La ' risposta ' di Jon Skeet .
Kenny Evitt,

1
@Oded non puoi presumere che il server sarà su UTC, ho visto server di produzione in cui il fuso orario era "UTC" ma aveva l'ora legale applicata, quindi in realtà era UTC + 1 per oltre la metà dell'anno. Concorda con @abatishchev di essere esplicito e di usare DateTime.UtcNowe GETUTCDATE(), mostra anche altri sviluppatori che ci hai davvero pensato
ono2012

Risposte:


940

Riepilogo delle risposte e altri dati: (si prega di aggiungere il proprio)

Fare:

  • Ogni volta che ti riferisci a un momento esatto, persisti l'ora secondo uno standard unificato che non è influenzato dall'ora legale. (GMT e UTC sono equivalenti a questo proposito, ma si preferisce usare il termine UTC. Si noti che UTC è anche noto come ora Zulu o Z. )
  • Se invece si sceglie di persistere un orario utilizzando un valore di ora locale, includere l'offset dell'ora locale per questo particolare orario da UTC (questo offset può cambiare nel corso dell'anno), in modo che il timestamp possa successivamente essere interpretato in modo inequivocabile.
  • In alcuni casi, potrebbe essere necessario memorizzare sia l'ora UTC sia l'ora locale equivalente. Spesso questo viene fatto con due campi separati, ma alcune piattaforme supportano un datetimeoffsettipo che può memorizzare entrambi in un singolo campo.
  • Quando si memorizzano i timestamp come valore numerico, usare il tempo Unix - che è il numero di secondi interi da allora 1970-01-01T00:00:00Z(esclusi i secondi bisestili). Se hai bisogno di maggiore precisione, usa invece i millisecondi. Questo valore deve essere sempre basato su UTC, senza alcuna regolazione del fuso orario.
  • Se in seguito potrebbe essere necessario modificare il timestamp, includere l'ID del fuso orario originale in modo da poter determinare se l'offset potrebbe essere cambiato rispetto al valore originale registrato.
  • Quando si pianificano eventi futuri, in genere si preferisce l'ora locale anziché UTC, poiché è comune che l'offset cambi. Vedi la risposta e il post sul blog .
  • Quando si memorizzano intere date, come compleanni e anniversari, non convertire in UTC o in qualsiasi altro fuso orario.
    • Se possibile, archiviare in un tipo di dati solo data che non include un'ora del giorno.
    • Se tale tipo non è disponibile, assicurarsi di ignorare sempre l'ora del giorno durante l'interpretazione del valore. Se non si può essere certi che l'ora del giorno verrà ignorata, scegliere 12:00 Noon, anziché 00:00 Midnight come ora rappresentativa più sicura in quel giorno.
  • Ricorda che gli offset del fuso orario non sono sempre un numero intero di ore (ad esempio, l'ora solare indiana è UTC + 05: 30 e il Nepal utilizza UTC + 05: 45).
  • Se si utilizza Java, utilizzare java.time per Java 8 e versioni successive.
  • Se si utilizza .NET , considerare l'utilizzo di Noda Time .
  • Se si utilizza .NET senza Noda Time, considerare che DateTimeOffsetspesso è una scelta migliore di DateTime.
  • Se si utilizza Perl, utilizzare DateTime .
  • Se si utilizza Python, utilizzare pytz o dateutil .
  • Se si utilizza JavaScript, utilizzare moment.js con l' estensione moment-timezone .
  • Se si utilizza PHP> 5.2, utilizzare le conversioni di fusi orari nativi fornite da DateTimee le DateTimeZoneclassi. Fai attenzione quando usi DateTimeZone::listAbbreviations()- vedi risposta . Per mantenere PHP con i dati Olson aggiornati, installare periodicamente il pacchetto PECL timezonedb ; vedi risposta .
  • Se si utilizza C ++, assicurarsi di utilizzare una libreria che utilizza correttamente implementa il database del fuso orario IANA . Questi includono cctz , ICU e la libreria "tz" di Howard Hinnant .
    • Non utilizzare Boost per le conversioni di fuso orario. Mentre la sua API afferma di supportare gli identificatori IANA standard (aka "zoneinfo"), li mappa grossolanamente su dati in stile POSIX, senza considerare la ricca cronologia dei cambiamenti che ogni zona potrebbe avere avuto. (Inoltre, il file non è più in manutenzione.)
  • Se usi Rust, usa chrono .
  • La maggior parte delle regole aziendali utilizza l'ora civile, anziché UTC o GMT. Pertanto, pianificare di convertire i timestamp UTC in un fuso orario locale prima di applicare la logica dell'applicazione.
  • Ricorda che i fusi orari e gli offset non sono fissi e possono cambiare. Ad esempio, storicamente Stati Uniti e Regno Unito hanno usato le stesse date per "balzare in avanti" e "ripiegare". Tuttavia, nel 2007 gli Stati Uniti hanno cambiato le date in cui vengono cambiati gli orologi. Ciò significa che per 48 settimane all'anno la differenza tra l'ora di Londra e quella di New York è di 5 ore e per 4 settimane (3 in primavera, 1 in autunno) sono 4 ore. Prestare attenzione a elementi come questo in tutti i calcoli che coinvolgono più zone.
  • Considera il tipo di ora (ora effettiva dell'evento, ora di trasmissione, ora relativa, ora storica, ora ricorrente) quali elementi (data / ora, offset del fuso orario e nome del fuso orario) è necessario memorizzare per il corretto recupero - vedere "Tipi di tempo" in questa risposta .
  • Mantieni sincronizzati i tuoi file tzdata di sistema operativo, database e applicazioni, tra loro e il resto del mondo.
  • Sui server, impostare gli orologi hardware e gli orologi del sistema operativo su UTC anziché su un fuso orario locale.
  • Indipendentemente dal precedente punto elenco, il codice lato server, compresi i siti Web, non dovrebbe mai prevedere che il fuso orario locale del server sia qualcosa di particolare. vedi risposta .
  • Preferisci lavorare con i fusi orari caso per caso nel codice dell'applicazione, piuttosto che a livello globale attraverso le impostazioni del file di configurazione o le impostazioni predefinite.
  • Utilizzare i servizi NTP su tutti i server.
  • Se si utilizza FAT32 , ricordare che i timestamp sono memorizzati nell'ora locale, non in UTC.
  • Quando si ha a che fare con eventi ricorrenti (ad esempio un programma televisivo settimanale), ricordare che l'ora cambia con l'ora legale e sarà diversa tra i fusi orari.
  • Interroga sempre i valori di data e ora come inclusivo con limite inferiore, esclusivo con limite superiore ( >=, <).

Non:

  • Non confondere un "fuso orario", ad esempio America/New_Yorkcon un "fuso orario", ad esempio -05:00. Sono due cose differenti. Vedi il tag del fuso orario wiki .
  • Non utilizzare l' Dateoggetto JavaScript per eseguire calcoli di data e ora nei browser Web meno recenti, poiché ECMAScript 5.1 e versioni precedenti presentano un difetto di progettazione che potrebbe utilizzare l'ora legale in modo errato. (Ciò è stato risolto nell'ECMAScript 6/2015).
  • Non fidarti mai dell'orologio del cliente. Potrebbe benissimo essere errato.
  • Non dire alle persone di "usare sempre UTC ovunque". Questo consiglio diffuso è miope di diversi scenari validi descritti in precedenza in questo documento. Utilizzare invece il riferimento temporale appropriato per i dati con cui si sta lavorando. (Il timestamp può utilizzare UTC, ma la pianificazione del tempo futuro e i valori di sola data no.)

test:

  • Durante il test, assicurati di testare i paesi negli emisferi occidentale, orientale, settentrionale e meridionale (in effetti in ogni quarto del globo, quindi 4 regioni), con entrambi l'ora legale in corso e non (dà 8), e un paese che lo fa non usare l'ora legale (altri 4 per coprire tutte le regioni, per un totale di 12).
  • Prova la transizione dell'ora legale, ad esempio quando sei in estate, seleziona un valore orario dall'inverno.
  • Testare casi limite, come un fuso orario UTC + 12, con l'ora legale, rendendo l'ora locale UTC + 13 in estate e persino i luoghi che sono UTC + 13 in inverno
  • Testa tutte le librerie e le applicazioni di terze parti e assicurati che gestiscano correttamente i dati del fuso orario.
  • Prova i fusi orari di mezz'ora, almeno.

Riferimento:

Altro:

  • Fai pressione sul tuo rappresentante per porre fine all'abominio che è l'ora legale. Possiamo sempre sperare ...
  • Ingresso per l' ora solare terrestre

31
L'uso del GMT non risolve davvero il problema, è ancora necessario capire qual è il delta giusto da applicare, ed è qui che sta tutta la complessità. Il delta può essere complesso da determinare nei sistemi utilizzati dagli utenti in diverse regioni (con diverse pianificazioni degli interruttori dell'ora legale) o nei sistemi che mostrano dati storici / futuri.
ckarras,

10
Questo è vero se tutto ciò che l'applicazione deve fare è visualizzare l'ora locale corrente. Ma se ad esempio abbiamo un server in Australia che deve visualizzare la data / ora per una transazione in Canada il 2 aprile 2006 (questo era l'ultimo anno prima che le regole di cambio dell'ora legale cambiassero in Canada) - hai una chiamata al sistema operativo che può fare DateTime ("2006/04/02 14: 35Z"). ToLocalTime (). WithDaylightSavingRules ("Canada", 2006)?
ckarras,

22
Sì, esiste una tale chiamata del sistema operativo in Windows: SystemTimeToTzSpecificLocation. msdn.microsoft.com/en-us/library/ms724949(VS.85).aspx
Michael Madsen

7
@tchrist Forse se sei persistente puoi.
Peter Ajtai,

16
Ricorda di convertire le date future (anche solo domani) in UTC perdi sempre qualcosa. Ad esempio, hai utilizzato un offset noto per effettuare quella conversione, ma poiché la data è futura, c'è sempre la possibilità che il gruppo che imposta tali regole cambierà quelle regole. Inoltre, è praticamente impossibile convertire alcune date future in UTC perché i tempi di ora legale non sono noti fino a quell'anno (alcuni paesi fissano le date ogni anno, non oltre 10+ anni in anticipo o in base a regole stabilite).
eselk,

319

Non sono sicuro di cosa posso aggiungere alle risposte sopra, ma qui ci sono alcuni punti da me:

Tipi di volte

Ci sono quattro diverse volte che dovresti considerare:

  1. Ora dell'evento: ad es. L'ora in cui si verifica un evento sportivo internazionale o un'incoronazione / morte / ecc. Ciò dipende dal fuso orario dell'evento e non dallo spettatore.
  2. Orario televisivo: ad esempio, un particolare programma TV viene trasmesso alle 21:00 ora locale in tutto il mondo. Importante quando si pensa alla pubblicazione dei risultati (ad esempio American Idol) sul proprio sito Web
  3. Tempo relativo: ad esempio: questa domanda ha una chiusura generica aperta in 21 ore. Questo è facile da visualizzare
  4. Orario ricorrente: ad esempio: uno spettacolo televisivo è attivo ogni lunedì alle 21:00, anche quando l'ora legale cambia.

C'è anche tempo storico / alternato. Questi sono fastidiosi perché potrebbero non essere associati all'ora standard. Ad esempio: date giuliane, date secondo un calendario lunare su Saturno, calendario Klingon.

La memorizzazione dei timestamp di inizio / fine in UTC funziona bene. Per 1, è necessario un nome di fuso orario dell'evento + offset memorizzato insieme all'evento. Per 2, è necessario un identificatore di ora locale memorizzato con ogni regione e un nome di fuso orario locale + offset memorizzati per ogni visualizzatore (è possibile derivarlo dall'IP se si è in una crisi). Per 3, memorizzare in secondi UTC e non è necessario il fuso orario. 4 è un caso speciale di 1 o 2 a seconda che si tratti di un evento globale o locale, ma è anche necessario archiviare un timestamp creato in modo da poter dire se una definizione del fuso orario è cambiata prima o dopo la creazione di questo evento. Ciò è necessario se è necessario mostrare dati storici.

Tempi di memorizzazione

  • Memorizza sempre l'ora in UTC
  • Converti in ora locale sul display (locale definito dall'utente che guarda i dati)
  • Quando si memorizza un fuso orario, è necessario il nome, la data e l'ora e l'offset. Ciò è necessario perché i governi a volte cambiano il significato dei loro fusi orari (ad esempio: il governo degli Stati Uniti ha cambiato le date dell'ora legale) e la tua applicazione deve gestire le cose con grazia ... ad esempio: il timestamp esatto quando gli episodi di LOST sono mostrati sia prima che dopo le regole dell'ora legale cambiato.

Offset e nomi

Un esempio di quanto sopra sarebbe:

La partita della finale di Coppa del mondo di calcio è avvenuta in Sudafrica (UTC + 2 - SAST) l'11 luglio 2010 alle 19:00 UTC.

Con queste informazioni, possiamo storicamente determinare l'ora esatta in cui si sono svolte le finali WCS 2010 anche se la definizione del fuso orario sudafricano cambia ed essere in grado di mostrarla agli spettatori nel loro fuso orario locale nel momento in cui interrogano il database.

Ora di sistema

È inoltre necessario mantenere sincronizzati i file tzdata del sistema operativo, del database e dell'applicazione, sia tra loro che con il resto del mondo, e testare ampiamente durante l'aggiornamento. Non è inaudito che un'app di terze parti da cui dipendi non ha gestito correttamente una modifica TZ.

Assicurati che gli orologi hardware siano impostati su UTC e, se stai eseguendo server in tutto il mondo, assicurati che i loro sistemi operativi siano configurati per utilizzare anche UTC. Ciò diventa evidente quando è necessario copiare i file di registro apache ruotati ogni ora dai server in più fusi orari. L'ordinamento per nome file funziona solo se tutti i file sono denominati con lo stesso fuso orario. Significa anche che non è necessario eseguire la matematica della data in testa quando si passa da una casella all'altra e è necessario confrontare i timestamp.

Inoltre, esegui ntpd su tutte le caselle.

clienti

Non fidarti mai del timestamp che ricevi da una macchina client come valido. Ad esempio, la data: intestazioni HTTP o una Date.getTime()chiamata javascript . Questi vanno bene se usati come identificatori opachi o quando si esegue la matematica della data durante una singola sessione sullo stesso client, ma non cercare di fare un riferimento incrociato di questi valori con qualcosa che hai sul server. I tuoi client non eseguono NTP e potrebbero non avere necessariamente una batteria funzionante per il loro orologio BIOS.

banalità

Infine, i governi a volte faranno cose molto strane:

L'ora legale nei Paesi Bassi era esattamente 19 minuti e 32.13 secondi davanti a UTC per legge dal 1909-05-01 al 1937-06-30. Questo fuso orario non può essere rappresentato esattamente utilizzando il formato HH: MM.

Ok, penso di aver finito.


6
Questa risposta ha alcuni punti importanti, in particolare ho voluto sottolineare questa parte "Tempo ricorrente: ad esempio: uno spettacolo televisivo è ogni lunedì alle 21:00, anche quando l'ora legale cambia" La memorizzazione dei tempi in UTC nel DB e quindi la conversione per la visualizzazione aiuta a gestire molti aspetti difficili della gestione dei fusi orari. Tuttavia, la gestione di "eventi ricorrenti" che attraversano le barriere dell'ora legale diventa molto più dura.
Jared Hales,

45
+1 per la curiosità. Mantenere il contenuto interessante rende questo compito più piacevole, il che può portare ad una maggiore produttività :)
Chris

4
Un sacco di cose buone in questa risposta, ma alcuni problemi. 1) Molte abbreviazioni del fuso orario sono ambigue. vedi qui 2) Non sempre vuoi archiviare in UTC. Il più delle volte - sì, ma il contesto è importante. Secondo i tuoi termini, l' ora della televisione non verrebbe memorizzata in UTC. Inoltre, a volte è illegale o contro la politica non memorizzare l'ora locale - che è dove le cose come DateTimeOffset(o equivalenti) sono utili. Altrimenti, scrivere bene.
Matt Johnson-Pint,

1
Quindi, tutti concordano sul fatto che la libreria Joda è di gran lunga lo strumento migliore disponibile per il lavoro. Tuttavia, è necessario continuare ad aggiornare (ricostruire) il file jar JODA come da questo articolo ( joda.org/joda-time/tz_update.html ) al fine di tenersi aggiornati con le ultime informazioni sul fuso orario. Esiste un modo standard per scaricare gli ultimi dati sul fuso orario dal sito Web IANA ( iana.org/time-zones ) e ricostruire la libreria joda? In altre parole, è possibile automatizzare questo processo anziché eseguirlo manualmente?
saravana_pc,

2
La curiosità olandese sembra legittima. ietf.org/rfc/rfc3339.txt sezione 5.8. A metà strada immaginava che qualcuno ci stesse prendendo in giro.
ruffin,

89

Questo è un problema importante e sorprendentemente difficile. La verità è che non esiste uno standard completamente soddisfacente per il tempo persistente. Ad esempio, lo standard SQL e il formato ISO (ISO 8601) non sono chiaramente sufficienti.

Dal punto di vista concettuale, di solito si tratta di due tipi di dati data-ora, ed è conveniente distinguerli (gli standard di cui sopra non lo fanno): " tempo fisico " e " tempo civile ".

Un istante "fisico" del tempo è un punto della linea temporale universale continua che la fisica affronta (ignorando la relatività, ovviamente). Questo concetto può essere adeguatamente codificato e persistente in UTC, ad esempio (se è possibile ignorare i secondi bisestili).

Un orario "civile" è una specifica datetime che segue le norme civili: un punto temporale qui è completamente specificato da un insieme di campi datetime (Y, M, D, H, MM, S, FS) più una TZ (specifica fuso orario) (anche un "calendario", in realtà; ma supponiamo che limitiamo la discussione al calendario gregoriano). Un fuso orario e un calendario consentono congiuntamente (in linea di principio) di mappare da una rappresentazione all'altra. Ma gli istanti di tempo civili e fisici sono tipi di grandezza fondamentalmente diversi e dovrebbero essere mantenuti concettualmente separati e trattati in modo diverso (un'analogia: matrici di byte e stringhe di caratteri).

La questione è confusa perché parliamo di questi tipi di eventi in modo intercambiabile e perché i tempi civili sono soggetti a cambiamenti politici. Il problema (e la necessità di distinguere questi concetti) diventa più evidente per gli eventi futuri. Esempio (tratto dalla mia discussione qui .

John registra nel suo calendario un promemoria per qualche evento al datetime 2019-Jul-27, 10:30:00, TZ = Chile/Santiago, (che ha offset GMT-4, quindi corrisponde a UTC 2019-Jul-27 14:30:00). Ma un giorno in futuro, il paese decide di cambiare l'offset TZ in GMT-5.

Ora, quando verrà il giorno ... dovrebbe attivarsi quel promemoria

A) 2019-Jul-27 10:30:00 Chile/Santiago = UTC time 2019-Jul-27 15:30:00?

o

B) 2019-Jul-27 9:30:00 Chile/Santiago = UTC time 2019-Jul-27 14:30:00?

Non esiste una risposta corretta, a meno che uno non sappia cosa intendesse John concettualmente quando ha detto al calendario "Per favore, chiamami 2019-Jul-27, 10:30:00 TZ=Chile/Santiago".

Intendeva un "appuntamento civile" ("quando gli orologi nella mia città indicano le 10:30")? In tal caso, A) è la risposta corretta.

Oppure intendeva un "istante fisico del tempo", un punto nella linea continua del tempo del nostro universo, diciamo "quando si verificherà la prossima eclissi solare". In tal caso, la risposta B) è quella corretta.

Alcune API Data / Ora ottengono questa distinzione giusta: tra queste, Jodatime , che è la base della prossima (terza!) API Java DateTime (JSR 310).


1
Un altro punto da considerare che non ho visto affrontato nelle API è che anche quando sono indicati l'ora e il fuso orario, ci sono almeno due significati plausibili per esempio "13: 00: 00EDT". Potrebbe essere riferito a qualcosa che è noto per essere accaduto alle 13:00 ora locale, che si credeva fosse l'ora legale orientale, o qualcosa che si è verificato nel momento in cui l'ora orientale ha toccato le 13:00, che si ritiene si sono verificati in un luogo osservando l'ora legale orientale. Se uno ha molti timestamp in cui le informazioni sul fuso orario potrebbero essere errate (ad es. File di fotocamere digitali) ...
supercat

1
... sapere se riflettono l'ora locale esatta o l'ora globale può essere importante per determinare come correggerli.
supercat,

3
Chiaramente John vuole A) perché le persone vanno a lavorare alle 8:30, qualunque sia l'ora legale o il fuso orario attualmente. Se entrano nell'ora legale, vanno a lavorare alle 8:30, quando escono dall'ora legale, vanno a lavorare alle 8:30. Se il Paese decide di passare a un altro fuso orario, andrà a lavorare alle 8:30 di ogni giorno
Gianluca Ghettini,

59

Fai una chiara separazione architettonica delle preoccupazioni - per sapere esattamente quale livello interagisce con gli utenti e deve cambiare la data e l'ora per / dalla rappresentazione canonica (UTC). La data e l'ora non UTC è una presentazione (segue il fuso orario locale degli utenti), l' ora UTC è un modello (rimane unica per i livelli di back-end e mid-end).

Inoltre, decidi qual è il tuo pubblico effettivo, cosa non devi servire e dove traccia la linea . Non toccare calendari esotici a meno che tu non abbia effettivamente clienti importanti lì e quindi prendere in considerazione server separati rivolti all'utente solo per quella regione.

Se è possibile acquisire e mantenere la posizione dell'utente, utilizzare la posizione per una conversione data-ora sistematica (ad esempio cultura .NET o una tabella SQL), ma fornire un modo per l'utente finale di scegliere le sostituzioni se la data-ora è fondamentale per i propri utenti.

Se sono implicati obblighi di revisione storici (come dire esattamente quando Jo in AZ ha pagato una fattura 2 anni fa a settembre), conservare sia l'ora locale sia l'ora locale (le tabelle di conversione cambieranno nel tempo).

Definire il fuso orario di riferimento temporale per i dati che arrivano in blocco , ad esempio file, servizi Web, ecc. Supponiamo che la società East Coast abbia un centro dati in CA: è necessario chiedere e sapere cosa usano come standard invece di supporre l'uno o l'altro.

Non fidarti degli offset di fuso orario incorporati nella rappresentazione testuale della data-ora e non accettare di analizzarli e seguirli. Invece, richiedere sempre che il fuso orario e / o il fuso orario siano definiti in modo esplicito . Puoi facilmente ricevere l'ora con l'offset PST ma l'ora è in realtà EST poiché è l'ora di riferimento del client e i record sono stati appena esportati su un server che si trova in PST.


40

È necessario conoscere il database Olson tz , disponibile su ftp://elsie.nci.nih.gov/pub http://iana.org/time-zones/ . Viene aggiornato più volte all'anno per far fronte ai cambiamenti spesso dell'ultimo minuto in cui (e se) passare dall'orario invernale a quello estivo (standard e diurno) in diversi paesi del mondo. Nel 2009, l'ultima versione è stata nel 2009; nel 2010 era il 2010n; nel 2011 era il 2011n; alla fine di maggio 2012, l'uscita era 2012c. Si noti che esiste un set di codice per gestire i dati e i dati effettivi del fuso orario stesso, in due archivi separati (tzcode20xxy.tar.gz e tzdata20xxy.tar.gz). Sia il codice che i dati sono di dominio pubblico.

Questa è la fonte dei nomi dei fusi orari come America / Los_Angeles (e sinonimi come US / Pacific).

Se è necessario tenere traccia delle diverse zone, è necessario il database Olson. Come altri hanno consigliato, si desidera anche archiviare i dati in un formato fisso - UTC è normalmente quello scelto - insieme a un record del fuso orario in cui sono stati generati i dati. È possibile che si desideri distinguere tra l'offset e UTC al momento e il nome del fuso orario; che può fare la differenza in seguito. Inoltre, sapere che è attualmente 2010-03-28T23: 47: 00-07: 00 (USA / Pacifico) può o non può aiutarti a interpretare il valore 2010-11-15T12: 30 - presumibilmente specificato in PST ( Pacific Standard Time) anziché PDT (Pacific Daylight Saving Time).

Le interfacce della libreria C standard non sono terribilmente utili con questo tipo di cose.


I dati di Olson si sono spostati, in parte perché AD Olson si ritirerà presto, e in parte perché c'era una causa (ora respinta) contro i manutentori per violazione del copyright. Il database dei fusi orari è ora gestito sotto l'egida di IANA , Internet Assigned Numbers Authority, e c'è un link in prima pagina a "Database dei fusi orari " . La mailing list di discussione è ora tz@iana.org; l'elenco degli annunci è tz-announce@iana.org.


12
Il database Olson contiene anche dati storici , il che lo rende particolarmente utile per la gestione dell'ora legale. Ad esempio, sa che un valore UTC corrispondente al 31 marzo 2000 negli Stati Uniti non è in ora legale, ma un valore UTC corrispondente al 31 marzo 2008 negli Stati Uniti lo è.
Josh Kelley,

3
Il consorzio Unicode mantiene una mappatura tra ID fuso orario Olson e ID fuso orario Windows: unicode.org/repos/cldr-tmp/trunk/diff/supplemental/…
Josh Kelley

Collegamento aggiornato per la pagina del Consorzio Unicode: unicode.org/repos/cldr-tmp/trunk/diff/supplemental/...
Span

Dove si possono trovare informazioni sull'analisi dei file Olson? Voglio compilarlo in una tabella db, ma non riesco a capire come dovrei leggere i file
shealtiel

@gidireich: le informazioni principali si trovano con i dati e non è facile da capire. La documentazione principale è nella zic.8pagina man (o zic.8.txt). Per ottenere queste informazioni avrai bisogno del tzcode2011i.tar.gzfile piuttosto che del tzdata2011i.tar.gzfile.
Jonathan Leffler,

26

In generale, includere la differenza di fuso orario locale (incluso la differenza di ora legale) nei timestamp memorizzati: UTC da solo non è sufficiente se si desidera successivamente visualizzare il timestamp nel suo fuso orario originale (e impostazione DST).

Tenere presente che l'offset non è sempre un numero intero di ore (ad esempio, l'ora solare indiana è UTC + 05: 30).

Ad esempio, formati adatti sono una tupla (tempo unix, offset in minuti) o ISO 8601 .


5
Per la visualizzazione, l'offset è perfetto. Se si desidera apportare modifiche, l'offset non è ancora sufficiente. Devi anche conoscere il fuso orario perché il nuovo valore potrebbe richiedere un offset diverso.
Matt Johnson-Pint,

23

Attraversare il confine tra "tempo del computer" e "tempo della gente" è un incubo. Il principale è che non esiste una sorta di standard per le regole che regolano i fusi orari e l'ora legale. I paesi sono liberi di modificare il proprio fuso orario e le regole dell'ora legale in qualsiasi momento, e lo fanno.

Alcuni paesi, ad esempio Israele, Brasile, decidono ogni anno quando avere l'ora legale, quindi è impossibile sapere in anticipo quando (se) l'ora legale sarà in vigore. Altri hanno fissato (ish) regole su quando è in vigore l'ora legale. Altri paesi non usano l'ora legale come tutti.

I fusi orari non devono differire di un'ora intera rispetto al GMT. Il Nepal è +5,45. Ci sono anche fusi orari che sono +13. Ciò significa che:

SUN 23:00 in Howland Island (-12)
MON 11:00 GMT 
TUE 00:00 in Tonga (+13)

sono tutti allo stesso tempo, eppure 3 giorni diversi!

Inoltre non esiste uno standard chiaro sulle abbreviazioni per i fusi orari e su come cambiano quando si è in DST, quindi si finisce con cose come questa:

AST Arab Standard Time     UTC+03
AST Arabian Standard Time  UTC+04
AST Arabic Standard Time   UTC+03

Il miglior consiglio è quello di stare il più lontano possibile dalle ore locali e attenersi all'UTC dove è possibile. Converti in orari locali solo all'ultimo momento possibile.

Durante il test, assicurati di testare i paesi negli emisferi occidentale e orientale, con entrambi l'ora legale in corso e non e un paese che non utilizza l'ora legale (6 in totale).


Per quanto riguarda Israele, questo è mezzo vero. Sebbene l'ora per la modifica dell'ora legale non sia una data specifica nel calendario giuliano, esiste una regola basata sul calendario ebraico (c'è stata una modifica nel 2014). Comunque, l'idea generale è corretta - queste cose potrebbero e cambiano di tanto in tanto
Yaron U.

1
Inoltre, AST = Atlantic Standard Time. Per quanto riguarda il "miglior consiglio", va bene come punto di partenza, ma devi leggere il resto di questa pagina e dire una piccola preghiera, e potresti ottenerlo giusto per un po '.
DavidWalley,

20

Per PHP:

La classe DateTimeZone in PHP> 5.2 è già basata sul DB Olson che altri citano, quindi se stai facendo conversioni del fuso orario in PHP e non nel DB, sei esente dal lavorare con i file Olson (difficili da capire).

Tuttavia, PHP non viene aggiornato con la stessa frequenza del DB Olson, quindi l'utilizzo delle conversioni di fuso orario di PHP può lasciare informazioni DST obsolete e influenzare la correttezza dei dati. Anche se questo non è previsto che accada di frequente, può accadere, e vi accadrà se si dispone di una grande base di utenti in tutto il mondo.

Per far fronte al problema precedente, utilizzare il pacchetto pecl timezonedb . La sua funzione è aggiornare i dati del fuso orario di PHP. Installa questo pacchetto con la frequenza con cui viene aggiornato. (Non sono sicuro che gli aggiornamenti di questo pacchetto seguano esattamente gli aggiornamenti di Olson, ma sembra che vengano aggiornati con una frequenza che è almeno molto vicina alla frequenza degli aggiornamenti di Olson.)


18

Se il tuo design può adattarlo, evita la conversione dell'ora locale tutti insieme!

So che questo potrebbe sembrare folle, ma pensa a UX: gli utenti elaborano a colpo d'occhio date relative (oggi, ieri, lunedì prossimo) più veloci delle date assolute (17.09.2010, venerdì 17 settembre). E se ci pensi di più, l'accuratezza dei fusi orari (e dell'ora legale) è più importante quanto più la data è vicina now(), quindi se puoi esprimere date / orari in un formato relativo per +/- 1 o 2 settimane, il resto di le date possono essere UTC e non contano troppo per il 95% degli utenti.

In questo modo è possibile memorizzare tutte le date in UTC e fare i relativi confronti in UTC e mostrare semplicemente le date UTC dell'utente al di fuori della soglia relativa.

Ciò può valere anche per l'input dell'utente (ma generalmente in modo più limitato). La selezione da un menu a discesa che contiene solo {Ieri, Oggi, Domani, Lunedi prossimo, Giovedi prossimo} è molto più semplice e facile per l'utente di un selezionatore di date. I selettori di data sono alcuni dei componenti che inducono dolore nel compilare i moduli. Naturalmente questo non funzionerà in tutti i casi, ma puoi vedere che ci vuole solo un po 'di design intelligente per renderlo molto potente.


16

Anche se non l'ho provato, un approccio alle regolazioni del fuso orario che troverei convincente sarebbe il seguente:

  1. Conservare tutto in UTC.

  2. Creare una tabella TZOffsetscon tre colonne: RegionClassId, StartDateTime e OffsetMinutes (int, in minuti).

Nella tabella, memorizza un elenco di date e orari in cui l'ora locale è cambiata e di quanto. Il numero di regioni nella tabella e il numero di date dipendono dall'intervallo di date e aree del mondo che devi supportare. Pensa a questo come se fosse una data "storica", anche se le date dovrebbero includere il futuro ad un certo limite pratico.

Quando è necessario calcolare l'ora locale di qualsiasi ora UTC, basta fare questo:

SELECT DATEADD('m', SUM(OffsetMinutes), @inputdatetime) AS LocalDateTime
FROM   TZOffsets
WHERE  StartDateTime <= @inputdatetime
       AND RegionClassId = @RegionClassId;

Potresti voler memorizzare nella cache questa tabella nella tua app e utilizzare LINQ o altri mezzi simili per eseguire le query anziché colpire il database.

Questi dati possono essere distillati dal database tz di dominio pubblico .

Vantaggi e note a piè di pagina di questo approccio:

  1. Nessuna regola è inserita nel codice, è possibile regolare prontamente gli offset per nuove regioni o intervalli di date.
  2. Non è necessario supportare tutti gli intervalli di date o aree geografiche, è possibile aggiungerli secondo necessità.
  3. Le regioni non devono corrispondere direttamente ai confini geopolitici e per evitare la duplicazione delle righe (ad esempio, la maggior parte degli stati negli Stati Uniti gestisce l'ora legale allo stesso modo), è possibile avere voci RegionClass ampie che collegano in un'altra tabella a elenchi più tradizionali di stati, paesi, ecc.
  4. Per situazioni come gli Stati Uniti in cui la data di inizio e fine dell'ora legale è cambiata negli ultimi anni, è abbastanza facile da gestire.
  5. Poiché anche il campo StartDateTime può memorizzare un orario, il tempo di sostituzione standard delle 2:00 AM viene gestito facilmente.
  6. Non ovunque nel mondo utilizza un ora legale di 1 ora. Questo gestisce facilmente quei casi.
  7. La tabella dei dati è multipiattaforma e potrebbe essere un progetto open source separato che potrebbe essere utilizzato dagli sviluppatori che utilizzano quasi qualsiasi piattaforma di database o linguaggio di programmazione.
  8. Questo può essere utilizzato per gli offset che non hanno nulla a che fare con i fusi orari. Ad esempio, gli aggiustamenti di 1 secondo che si verificano di tanto in tanto per adattarsi alla rotazione della Terra, agli aggiustamenti storici verso e all'interno del calendario gregoriano, ecc.
  9. Dato che si trova in una tabella di database, le query standard sui rapporti, ecc. Possono sfruttare i dati senza passare attraverso il codice della logica aziendale.
  10. Gestisce anche gli offset di fuso orario se lo si desidera e può anche tenere conto di casi storici speciali in cui una regione è assegnata a un altro fuso orario. Tutto ciò che serve è una data iniziale che assegni un fuso orario a ciascuna regione con una data di inizio minima. Ciò richiederebbe la creazione di almeno una regione per ciascun fuso orario, ma consentirebbe di porre domande interessanti come: "Qual è la differenza di ora locale tra Yuma, Arizona e Seattle, Washington, il 2 febbraio 1989 alle 5:00?" (Basta sottrarre una somma () dall'altra).

Ora, l'unico svantaggio di questo approccio o di qualsiasi altra è che le conversioni da ora locale a GMT non sono perfetti, dal momento che ogni cambiamento dell'ora legale che ha un offset per l'orologio negativo si ripete un dato tempo locale. Non ho modo di affrontarlo, temo, il che è uno dei motivi per cui la memorizzazione dell'ora locale è una brutta notizia.


8
L'idea del database è già stata implementata come database Olson. Mentre l'ora legale crea una sovrapposizione che specifica il fuso orario specifico della luce del giorno può aiutare a risolvere il problema. 2:15 EST e 2:15 EDT sono tempi diversi. Come notato in altri post, la specifica dell'offset risolve anche l'ambiguità.
BillThor,

5
Il grosso problema con la gestione del proprio database è l'aggiornamento. Olson e Windows sono gestiti per te. Ho avuto più di un caso di transizioni DST errate perché le tabelle non erano aggiornate. Strapparli completamente e fare affidamento su un database a livello di framework o di sistema operativo è molto più affidabile.
Matt Johnson-Pint,

4
Non creare il tuo database : affidati sempre all'API di sistema!
Alex,

15

Di recente ho avuto un problema in un'applicazione Web in cui su un post-back Ajax il datetime che tornava al mio codice lato server era diverso dal datetime offerto.

Molto probabilmente ha avuto a che fare con il mio codice JavaScript sul client che ha creato la data per la restituzione al client come stringa, perché JavaScript si stava adeguando per fuso orario e ora legale e in alcuni browser il calcolo per quando applicare l'ora legale sembrava essere diverso rispetto ad altri.

Alla fine ho optato per rimuovere completamente i calcoli di data e ora sul client e ho registrato di nuovo sul mio server su una chiave intera che è stata poi tradotta in data e ora sul server, per consentire trasformazioni coerenti.

Il mio apprendimento da questo: non utilizzare calcoli di data e ora JavaScript nelle applicazioni Web a meno che ASSOLUTAMENTE sia necessario.


Javascript viene eseguito sul computer client, non sul server. Il datetime di base di Javascript è il datetime del client, non il datetime del server.
BalusC

Ciao BalusC. Lo capisco (dal mio post originale: "script javacode sul client che ha creato la data ..."). Il mio problema era che alcune macchine client elaboravano l'ora legale in un modo e altri in un altro modo. Pertanto ho spostato tutta quell'elaborazione sul lato server per impedire la stranezza del browser
Joon

@ Joon — e ci sono bug nelle implementazioni javascript che non puoi rilevare o consentire. Quindi sì, non usare mai i calcoli della data ECMAScript sul lato client per le cose che contano (anche se altrimenti puoi fare un buon lavoro).
RobG,

14

L'ho riscontrato su due tipi di sistemi, "sistemi di pianificazione dei turni (ad es. Operai di fabbrica)" e "sistemi di gestione dipendenti dal gas) ...

Le lunghe giornate di 23 e 25 ore sono un dolore da affrontare, così come i turni di 8 ore che durano 7 ore o 9 ore. Il problema è che scoprirai che ogni cliente, o anche dipartimento del cliente, ha regole diverse che ha creato (spesso senza documentare) su ciò che fa in questi casi speciali.

È preferibile non porre alcune domande al cliente fino a quando non avrà pagato il software "standard". È molto raro trovare un cliente che pensa direttamente a questo tipo di problema quando acquista un software.

Penso che in ogni caso dovresti registrare l'ora in UTC e convertirla in / dall'ora locale prima di memorizzare la data / ora. Tuttavia, anche sapere in quali ore è il momento può essere difficile con l'ora legale e i fusi orari.


6
La mia ragazza, un'infermiera, lavora di notte e devono scrivere il fuso orario durante il passaggio all'ora legale. Ad esempio, 2AM CST vs 2AM CDT
Joe Phillips,

1
Sì, questo è comune: quando si calcola una media giornaliera (civile), è necessario affrontare giorni di 23, 24 o 25 ore. Di conseguenza, quando si calcola aggiungere 1 giorno non si aggiungono 24 ore ! In secondo luogo, non provare a creare il tuo codice fuso orario; usa solo l'API di sistema. E non dimenticare di aggiornare ciascun sistema distribuito al fine di ottenere il database del fuso orario aggiornato .
Alex,

12

Per il web, le regole non sono così complicate ...

  • Sul lato server, utilizzare UTC
  • Lato client, usa Olson
    • Motivo: le compensazioni UTC non sono sicure (ad es. New York è EST (UTC - 5 ore) parte dell'anno, EDT (UTC - 4 ore) resto dell'anno).
    • Per la determinazione del fuso orario sul lato client, sono disponibili due opzioni:
      • 1) Configura zona utente (più sicura)
      • 2) Zona di rilevamento automatico

Il resto è solo la conversione UTC / locale utilizzando le librerie datetime lato server. Buono per andare ...


2
Questo è un buon consiglio come punto di partenza, ma dipende totalmente dall'applicazione. Questo potrebbe andare bene per un sito web amichevole, ma se nella tua applicazione sono presenti aspetti legali / giurisdizionali / finanziari su cui qualcuno potrebbe fare causa (ne ho lavorato su diversi), allora si tratta di una semplificazione eccessiva perché esistono diversi tipi di " time ", come indicato altrove in questa pagina.
DavidWalley,

12

Quando si tratta di applicazioni in esecuzione su un server , inclusi siti Web e altri servizi di back-end, l'applicazione deve essere ignorata dall'impostazione del fuso orario del server.

Il consiglio comune è di impostare il fuso orario del server su UTC. Questa è davvero una buona pratica, ma è lì come un cerotto per applicazioni che non seguono altre migliori pratiche. Ad esempio, un servizio potrebbe scrivere nei file di registro con timestamp locali anziché timestamp basati su UTC, creando così ambiguità durante la transizione di fallback dell'ora legale. Impostazione fuso orario del server per UTC risolverà quel applicazione. Tuttavia, la vera soluzione sarebbe che l'applicazione accedesse utilizzando UTC per cominciare.

Il codice lato server, inclusi i siti Web, non dovrebbe mai prevedere che il fuso orario locale del server sia qualcosa di particolare.

In alcune lingue, il fuso orario locale può facilmente insinuarsi nel codice dell'applicazione. Ad esempio, il DateTime.ToUniversalTimemetodo in .NET converte dal fuso orario locale in UTC e la DateTime.Nowproprietà restituisce l'ora corrente nel fuso orario locale. Inoltre, il Datecostruttore in JavaScript utilizza il fuso orario locale del computer. Ci sono molti altri esempi come questo. È importante esercitarsi nella programmazione difensiva, evitando qualsiasi codice che utilizza l'impostazione del fuso orario locale del computer.

Prenota utilizzando il fuso orario locale per il codice lato client, ad esempio applicazioni desktop, applicazioni mobili e JavaScript lato client.


11

Mantieni i tuoi server impostati su UTC e assicurati che siano tutti configurati per ntp o equivalenti.

UTC evita problemi di ora legale e server non sincronizzati possono causare risultati imprevedibili che richiedono un po 'di tempo per la diagnosi.


9

Fai attenzione quando gestisci i timestamp memorizzati nel filesystem FAT32 - è sempre persistito nelle coordinate temporali locali (che includono l'ora legale - vedi l' articolo msdn ). Mi sono bruciato su quello.


Ottimo punto NTFS non ha questo problema, ma alcune persone usano ancora FAT32, specialmente su chiavi USB.
Matt Johnson-Pint,

7

Un'altra cosa, assicurarsi che i server abbiano applicato la patch di ora legale aggiornata.

Abbiamo avuto una situazione l'anno scorso in cui i nostri tempi erano costantemente fuori di un'ora per un periodo di tre settimane per gli utenti del Nord America, anche se stavamo usando un sistema basato su UTC.

Alla fine si è scoperto che erano i server. Avevano solo bisogno di applicare una patch aggiornata ( Windows Server 2003 ).


6

L' DateTimeZone::listAbbreviations()output di PHP

Questo metodo PHP restituisce un array associativo contenente alcuni fusi orari "principali" (come CEST), che da soli contengono fusi orari "geografici" più specifici (come Europa / Amsterdam).

Se stai usando questi fusi orari e le loro informazioni offset / ora legale, è estremamente importante realizzare quanto segue:

Sembra che siano incluse tutte le diverse configurazioni offset / DST (comprese le configurazioni storiche) di ogni fuso orario!

Ad esempio, Europa / Amsterdam si trovano sei volte nell'output di questa funzione. Due occorrenze (offset 1172/4772) sono per il tempo di Amsterdam usato fino al 1937; due (1200/4800) sono per il tempo che fu usato tra il 1937 e il 1940; e due (3600/4800) sono per il tempo impiegato dal 1940.

Pertanto, non è possibile fare affidamento sulle informazioni offset / DST restituite da questa funzione come correntemente / in uso!

Se vuoi conoscere l'offset / ora legale corrente di un determinato fuso orario, dovrai fare qualcosa del genere:

<?php
$now = new DateTime(null, new DateTimeZone('Europe/Amsterdam'));
echo $now->getOffset();
?>

5

Se ti capita di mantenere attivi i sistemi di database in esecuzione con l'ora legale, controlla attentamente se è necessario arrestarli durante la transizione in autunno. A Mandy DBS (o anche ad altri sistemi) non piace passare due volte lo stesso punto nell'ora (locale), che è esattamente ciò che accade quando si torna indietro l'orologio in autunno. SAP ha risolto questo problema con una soluzione (IMHO davvero ordinata): invece di tornare indietro, lasciano l'orologio interno a metà della normale velocità per due ore ...


4

Stai utilizzando .NET Framework ? In tal caso, lascia che ti presenti il tipo DateTimeOffset , aggiunto con .NET 3.5.

Questa struttura contiene sia a DateTimeche Offset ( TimeSpan), che specifica la differenza tra DateTimeOffsetdata e ora dell'istanza e Coordinated Universal Time (UTC).

  • Il DateTimeOffset.Nowmetodo statico restituirà DateTimeOffset un'istanza costituita dall'ora corrente (locale) e dall'offset locale (come definito nelle informazioni regionali del sistema operativo).

  • Il DateTimeOffset.UtcNowmetodo statico restituirà DateTimeOffsetun'istanza consistente nell'ora corrente in UTC (come se fossi a Greenwich).

Altri tipi utili sono le classi TimeZone e TimeZoneInfo .


Questa non è una soluzione al problema presentato.
caradrye,

4

Per coloro che lottano con questo su .NET , vedi se usare DateTimeOffsete / o TimeZoneInfovale la pena.

Se desideri utilizzare i fusi orari IANA / Olson o se i tipi integrati non sono sufficienti per le tue esigenze, dai un'occhiata a Noda Time , che offre un'API di data e ora molto più intelligente per .NET.


4

Le regole aziendali dovrebbero sempre funzionare sul tempo civile (a meno che non ci sia una legislazione che dice diversamente). Sii consapevole che il tempo civile è un disastro, ma è ciò che la gente usa, quindi è ciò che è importante.

Internamente, mantieni i timestamp in qualcosa come il tempo civile dei secondi dall'epoca. L' epoca non conta particolarmente (preferisco l' epoca Unix ) ma rende le cose più facili dell'alternativa. Fai finta che i secondi bisestili non esistano a meno che tu non stia facendo qualcosa che ne ha davvero bisogno (ad esempio, il monitoraggio satellitare). La mappatura tra i timestamp e il tempo visualizzato è l'unico punto in cui dovrebbero essere applicate le regole dell'ora legale ; le regole cambiano frequentemente (a livello globale, più volte all'anno; incolpare i politici), quindi è necessario assicurarsi di non codificare a fondo la mappatura. Il database TZ di Olson ha un valore inestimabile.


3
Il problema qui è che l'ora civile (ovvero l'ora del calendario) non rappresenta correttamente un singolo momento nel tempo. Se segui l'approccio dei secondi dall'epoca, spiegherai davvero ogni momento che è stato saltato o riavvolto per le transizioni dell'ora legale? Probabilmente no. La base dell'epoca funziona solo contro UTC o altri riferimenti fissi a tempo istantaneo.
Matt Johnson-Pint,

@MattJohnson Da qui la parte "regole aziendali". Se le regole dicono che succede qualcosa alle 2:30 del mattino (o in qualsiasi momento), accadrà due volte in un giorno all'anno e mai in un giorno all'anno. Questo è ciò che il cliente si aspetta che accada se non chiarisce la regola.
user253751

Mantenere i timestamp interni nel tempo civile può essere molto complicato. Tenendolo come pochi secondi poiché un'epoca è ancora più complicata, direi assolutamente pericoloso. Sono sicuro che ci sono persone che lo fanno, e potrebbe essere possibile farlo funzionare correttamente la maggior parte delle volte se stai molto attento, ma non può essere considerato una buona pratica o una raccomandazione generale.
Steve Summit,

2

Volevo solo sottolineare due cose che sembrano inaccurate o almeno confuse:

Mantenere sempre l'ora secondo uno standard unificato che non è influenzato dall'ora legale. GMT e UTC sono stati citati da persone diverse, anche se UTC sembra essere menzionato più spesso.

Per (quasi) tutti gli scopi di calcolo pratici, UTC è, in effetti, GMT. A meno che non vedi un timestamp con un secondo frazionario, hai a che fare con GMT che rende questa distinzione superflua.

Includere la differenza di fuso orario locale così com'è (incluso la differenza di ora legale) quando si memorizzano i timestamp.

Un timestamp è sempre rappresentato in GMT e quindi non ha offset.


1
La differenza di fuso orario locale ti consentirà di ricreare il "tempo della parete" originale dell'evento. Se non si memorizza questo campo aggiuntivo, questi dati vengono persi.
nogridbag,

Sì, tranne gli offset UTC e GMT sono inversi. Ad esempio UTC-0700 è uguale a GMT + 0700. In realtà, tutto il digitale dovrebbe usare UTC in questi giorni.
Matt Johnson-Pint,

1
@Matt: sei sicuro che gli offset UTC e GMT siano inversi? dove posso leggerlo?
Reto Höhener,

In realtà, penso di aver sbagliato prima. GMT e UTC non sono invertiti. È che ci sono implementazioni che le mostrano inverse, come il database IANA / Olson / TZDB. Vedi qui . Un'altra area che vedi gli offset nell'inverso è nella funzione getTimezoneOffset () di javascript.
Matt Johnson-Pint,

@MattJohnson: quelli sono degli hack e dovrebbero essere aboliti.
Alix Axel,

2

Ecco la mia esperienza: -

(Non richiede alcuna libreria di terze parti)

  • Sul lato server, memorizzare gli orari in formato UTC in modo che tutti i valori di data / ora nel database siano in un unico standard indipendentemente dalla posizione di utenti, server, fusi orari o ora legale.
  • Sul livello dell'interfaccia utente o nelle e-mail inviate all'utente, è necessario mostrare i tempi in base all'utente. Per questo motivo, devi avere un offset del fuso orario dell'utente in modo da poter aggiungere questo offset al valore UTC del tuo database che risulterà nell'ora locale dell'utente. Puoi prendere l'offset del fuso orario dell'utente quando si iscrive o puoi rilevarlo automaticamente nelle piattaforme web e mobile. Per i siti Web, la funzione getTimezoneOffset () di JavaScript è uno standard dalla versione 1.0 ed è compatibile con tutti i browser. (Rif: http://www.w3schools.com/jsref/jsref_getTimezoneOffset.asp )

Questo non funziona se si considerano le modifiche all'ora legale. getTimezoneOffsetrestituisce l'offset per la data e l'ora in cui lo si chiama. Tale offset può cambiare quando un fuso orario passa o esce dall'ora legale. Vedi "fuso orario! = Offset" nel wiki del fuso orario .
Matt Johnson-Pint,

1
Se si desidera memorizzare un allarme come "fare qualcosa alle 10:00", non è possibile memorizzarlo in UTC, a causa dei turni di ora legale. È necessario memorizzarlo in relazione all'ora locale.
Alex,

2

Il video di Tom Scott sui fusi orari su YouTube sul canale Computerphile ha anche una descrizione piacevole e divertente dell'argomento. Esempi inclusi:

  • Samoa (un'isola nell'Oceano Pacifico) spostando il suo fuso orario in avanti di 24 ore per facilitare gli scambi con l'Australia e la Nuova Zelanda,
  • Cisgiordania , dove 2 popolazioni di persone stanno seguendo diversi fusi orari,
  • Il 18 ° secolo cambia dal calendario giuliano al calendario gregoriano (che è accaduto nel 20 ° secolo in Russia).

1

In realtà, kernel32.dll non esporta SystemTimeToTzSpecificLocation. Esporta tuttavia i due seguenti: SystemTimeToTzSpecificLocalTime e TzSpecificLocalTimeToSystemTime ...


1

Non fare affidamento solo su costruttori come

 new DateTime(int year, int month, int day, int hour, int minute, TimeZone timezone)

Possono generare eccezioni quando un determinato orario non esiste a causa dell'ora legale. Invece, crea i tuoi metodi per creare tali date. In essi, individuare eventuali eccezioni che si verificano a causa dell'ora legale e regolare il tempo necessario con l'offset di transizione. L'ora legale può verificarsi in date diverse e ad orari diversi (anche a mezzanotte per il Brasile) in base al fuso orario.


1

Solo un esempio per dimostrare che il tempo di gestione è l'enorme casino descritto e che non si può mai essere compiacenti. In diversi punti di questa pagina i secondi da saltare sono stati ignorati.

Diversi anni fa, il sistema operativo Android utilizzava i satelliti GPS per ottenere un riferimento orario UTC, ma ignorava il fatto che i satelliti GPS non utilizzano i secondi saltanti. Nessuno se ne accorse fino a quando non vi fu confusione a Capodanno, quando gli utenti di telefoni Apple e gli utenti di telefoni Android fecero i loro conto alla rovescia a circa 15 secondi di distanza.

Penso che da allora sia stato risolto, ma non si sa mai quando questi "dettagli minori" torneranno a perseguitarti.


1
  • Mai e poi mai memorizzare l'ora locale senza il suo offset UTC (o un riferimento al fuso orario) - esempi di come non farlo include FAT32 e struct tmin C.¹
  • Comprendi che un fuso orario è una combinazione di
    • una serie di offset UTC (ad es. +0100 in inverno, +0200 in estate)
    • regole per quando avviene il passaggio (che può cambiare nel tempo: ad esempio, negli anni '90 l'UE ha armonizzato il passaggio come nelle ultime domeniche di marzo e ottobre, alle 02:00 ora solare / 03:00 ora legale; in precedenza ciò differiva tra gli stati membri).

¹ Alcune implementazioni struct tmmemorizzano l'offset UTC, ma questo non è diventato standard.


-4

Nel trattare con i database (in particolare MySQL , ma questo vale per la maggior parte dei database), ho trovato difficile memorizzare UTC.

  • I database di solito funzionano con il datetime del server per impostazione predefinita (ovvero CURRENT_TIMESTAMP).
  • Potrebbe non essere possibile modificare il fuso orario del server.
  • Anche se sei in grado di modificare il fuso orario, potresti avere un codice di terze parti che prevede che il fuso orario del server sia locale.

Ho trovato più semplice archiviare il datetime del server nel database, quindi consentire al database di riconvertire il datetime memorizzato in UTC (ovvero UNIX_TIMESTAMP ()) nelle istruzioni SQL. Successivamente puoi usare il datetime come UTC nel tuo codice.

Se hai il 100% di controllo sul server e su tutto il codice, probabilmente è meglio cambiare il fuso orario del server in UTC.


L'ora locale (l'ora del server) può essere ambigua durante le transizioni dell'ora legale in stile "fallback". Non è affidabile da usare come descritto. Potrebbe esserci più di un'ora UTC che l'ora locale del server potrebbe rappresentare.
Matt Johnson-Pint,

L'ora locale va perfettamente bene se il server si trova in un fuso orario sano, ovvero uno che non fa l'ora legale.
Sayap
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.