È sempre una buona idea conservare il tempo in UTC o è questo il caso in cui è meglio memorizzare in ora locale?

In genere, è consigliabile archiviare il tempo in UTC e come indicato qui e qui

Supponiamo che ci sia un evento ricorrente diciamo ora di fine che è sempre nella stessa ora locale diciamo 17:00 indipendentemente dal fatto che sia triggers o distriggersta l’ora legale per quel fuso orario. Inoltre, è necessario non modificare l’ora manualmente quando l’ora legale si triggers o si distriggers per un determinato fuso orario. È anche un requisito che ogni volta che viene richiesto l’orario di fine da qualsiasi altro sistema tramite API (es. GetEndTimeByEvent) invia sempre l’ora di fine nel formato UTC.

Approccio 1: se si decide di memorizzare in UTC , può essere memorizzato nella tabella del database come di seguito.

Event UTCEndTime ===================== ABC 07:00:00 MNO 06:00:00 PQR 04:00:00 

Per il primo evento ABC, l’ora di fine in UTC è 07:00 che, se convertita per la visualizzazione da UTC a ora locale il 1 luglio 2012, si tradurrà in 17:00 ora locale e se convertita il 10-ott-2012 ( la data in cui l’ora legale è triggersta per il fuso orario) si tradurrà in 6 pm, che non è l’ora esatta corretta.

Un modo ansible che potrei pensare è quello di memorizzare l’ora legale nella colonna aggiuntiva e utilizzare quell’ora in cui il fuso orario ha l’ora legale triggersta.

Approccio 2: Tuttavia, se è archiviato come Ora locale come di seguito, ad esempio per l’evento ABC, sarà sempre 17:00 in qualsiasi data in quanto non vi è alcuna conversione da UTC a ora locale.

 Event LocalEndTime ======================= ABC 17:00:00 MNO 16:00:00 PQR 14:00:00 

E un livello applicazione converte l’ora locale in ora UTC per l’invio ad altri sistemi tramite (API GetEndTimeByEvent).

È ancora una buona idea conservare l’ora in UTC in questo caso? Se sì, allora come ottenere un orario locale costante?

Domande correlate: esiste sempre una buona ragione per archiviare il tempo non in UTC?

Penso che per rispondere a questa domanda dovremmo pensare ai vantaggi dell’uso di UTC per archiviare timestamp.

Personalmente ritengo che il principale vantaggio sia che il tempo è sempre (soprattutto) garantito per essere coerente . In altre parole, ogni volta che viene modificato il fuso orario o applicata l’ora legale, non si torna indietro o indietro nel tempo. Questo è particolarmente utile in filesystem, log e così via. Ma è necessario nella tua applicazione?

Pensa a due cose. In primo luogo, circa il tempo di spostamento dell’orologio DST. È probabile che i tuoi eventi si verifichino tra le 2:00 e le 3:00 (il giorno in cui viene effettuato lo spostamento dell’orologio)? Cosa dovrebbe succedere allora?

In secondo luogo, l’applicazione sarà soggetta a cambiamenti effettivi nei fusi orari? In altre parole, hai intenzione di volare con esso da Londra a Varsavia e cambiare il fuso orario del computer in modo appropriato? Cosa dovrebbe succedere in quel caso?

Se hai risposto no a entrambe le domande, allora stai meglio con l’ora locale. Renderà la tua applicazione più semplice. Ma se hai risposto almeno una volta, allora penso che dovresti pensarci di più.


E questo era tutto sul database. L’altra cosa è il formato dell’ora utilizzato internamente dall’applicazione, e ciò dovrebbe dipendere da ciò che effettivamente farai in quel momento.

Hai menzionato il fatto di esporre il tempo tramite un’API. L’applicazione interroga il database su ogni richiesta? Se memorizzi l’ora internamente come UTC, dovrai farlo o comunque assicurarti che su DST / fuso orario cambiare i tempi memorizzati nella cache verrà regolato / potato.

Farà qualcosa con il tempo stesso? Come stampare l’evento avverrà in 8 ore o sospendere se stesso per circa quel tempo? Se sì, allora UTC sarà probabilmente migliore. Certo, è necessario pensare a tutti i problemi citati.

Mi piace pensarlo in questo modo:

I computer non si preoccupano del tempo in quanto rappresentazione comprensibile all’uomo. Non si preoccupano dei fusi orari, della formattazione delle stringhe di data e ora o altro. Solo gli umani si preoccupano di come interpretare e rappresentare il tempo.

Lascia che il database faccia ciò che è buono: il tempo di archiviazione come numero – un’epoca UNIX (numero di secondi trascorsi dal 1970-01-01) o un timestamp UTC (nessun fuso orario o informazioni sull’ora legale). Solo preoccupati di rappresentare il tempo in un modo comprensibile all’uomo quando devi. Ciò significa nella logica dell’applicazione, nel sistema di reporting, nell’applicazione della console o in qualsiasi altro luogo in cui un essere umano visualizzerà i dati.

Quanto segue non si applica a un prodotto SaaS globale multi-tenant, quindi questa opinione è rivolta a semplici sviluppatori di app “Line of Business”.

La memorizzazione come UTC va bene, ma c’è un requisito che causa dolore se si fa questo: “Puoi scrivermi un rapporto che mi mostri quanti X si verificano al giorno?”

Se memorizzi le date come UTC, questo requisito causerà dolore; è necessario scrivere il codice di regolazione del fuso orario sul server delle applicazioni e nei rapporti; Ogni query ad-hoc eseguita sui dati che include criteri di data dovrà tenerne conto.

Se la tua domanda soddisfa i seguenti criteri:

  1. Ogni istanza è basata su un singolo fuso orario.
  2. Le transizioni del fuso orario sono di solito al di fuori dell’orario di ufficio o non ti interessa davvero “durate” delle cose al livello che un’oretta mancante o poco importa.

Ti suggerisco di memorizzare il datetime come ora locale, mentre usi una libreria che ti isola dai problemi di configurazione del fuso orario del server (es. Noda.Time nel mondo di .net).

Se i messaggi tra i sistemi utilizzano ISO 8601 e il database memorizza l’ora locale di origine + offset (come datetimeoffset in MSSQL o ISODate in Mongo come ISO 8601 lo cattura) e si utilizza solo DateTimeOffset in .NET o OffsetDateTime in Java o qualche equivalente nel tuo codice, quindi non sono necessarie conversioni. Devi solo riporlo. Tutte le funzioni di confronto funzioneranno.

Se la tua persistenza viene convertita in UTC, hai perso l’offset dal punto di vista dell’utente. La visualizzazione di quando un utente ha firmato un documento dieci anni fa è ora un problema difficile. Lavorare fuori da UTC significherà cercare le regole di DST che erano in gioco in quel momento in quel territorio. Incubo.

Credo che la ragione per cui siamo tutti così abituati a convertire in UTC per la persistenza sia perché non abbiamo mai avuto le giuste strutture dati / dati per permetterci di fare la cosa giusta.

Vorrei solo memorizzare la componente Time solo senza alcuna zona. Ogni volta che l’API deve servirlo, aggiungi la data corretta e convertila come ora locale in UTC per quella data.

Database = 17:00 (usa un timestamp senza data, ore come byte, minuti come byte, stringa)

Recupera = Data in cui vogliamo l’evento + Database 17:00 => Converti da locale a UTC

In questo modo servirai sempre l’ora esatta in UTC.

In realtà non stai memorizzando un punto specifico nel tempo come si presuppone la maggior parte delle API temporali. Utilizzare gli intervalli se il database lo supporta (PostgreSQL lo fa) o memorizzarlo come un numero intero che rappresenta il numero di secondi (minuti / ore) da mezzanotte o l’inizio corrispondente della pianificazione (lunedì, il primo del mese, ecc.). In entrambi i casi, hai perso un sacco di grattacapi a preoccuparti di come “Tempo” è gestito tra i sistemi e hai aggiunto solo un mal di testa molto piccolo di conversione dei secondi in ore del giorno nella tua visualizzazione.