Domanda DateTime.Now vs. DateTime.UtcNow


Mi sono chiesto quali sono esattamente i principi su come funzionano le due proprietà. So che il secondo è universale e fondamentalmente non si occupa dei fusi orari, ma qualcuno può spiegare in dettaglio come funzionano e quale dovrebbe essere utilizzato in quale scenario?


174
2017-09-15 10:57


origine


risposte:


DateTime.UtcNow ti dice la data e l'ora come sarebbe in Coordinated Universal Time, che è anche chiamato il fuso orario di Greenwich Mean Time - fondamentalmente come sarebbe se fossi a Londra, in Inghilterra, ma non durante l'estate. DateTime.Now dà la data e l'ora come sembrerebbe a qualcuno nella tua attuale localizzazione.

Consiglierei l'utilizzo DateTime.Now ogni volta che visualizzi una data per un essere umano - in questo modo si sentono a proprio agio con il valore che vedono - è qualcosa che possono facilmente confrontare con quello che vedono sul loro orologio o orologio. Uso DateTime.UtcNow quando si desidera archiviare le date o utilizzarle per calcoli successivi in ​​questo modo (in un modello client-server) i calcoli non vengono confusi dai client in fusi orari diversi dal proprio server o tra loro.


274
2017-09-15 11:02



È davvero molto semplice, quindi penso che dipenda dal tuo pubblico e da dove vivono.

Se non usi Utc, tu dovere conosci il fuso orario della persona a cui stai visualizzando le date e le ore - altrimenti dirai loro che è successo qualcosa alle 3 del pomeriggio in orario di sistema o server, quando è realmente accaduto alle 5 del pomeriggio, dove si trovano a vivere.

Noi usiamo DateTime.UtcNow perché abbiamo un pubblico globale sul Web e perché preferirei non tormentare tutti gli utenti per compilare un modulo che indichi in quale fuso orario vivono.

Visualizziamo anche i tempi relativi (2 ore fa, 1 giorno fa, ecc.) Finché il post non invecchia abbastanza che il tempo è "uguale" indipendentemente da dove si vive sulla Terra.


73
2017-09-15 11:03



Un concetto principale da comprendere in .NET è quello adesso è adesso ovunque nel mondo, indipendentemente dal fuso orario in cui ci si trova. Quindi, se si carica una variabile con DateTime.Now o DateTime.UtcNow, l'assegnazione è identica. * L'oggetto DateTime riconosce il fuso orario in cui ci si trova e lo tiene in considerazione indipendentemente del compito.

L'utilità di DateTime.UtcNow è utile quando si calcolano le date tra i limiti di Ora legale. Cioè, in luoghi che partecipano all'ora legale, a volte ci sono 25 ore da mezzogiorno a mezzogiorno del giorno seguente, e talvolta ci sono 23 ore tra mezzogiorno e mezzogiorno del giorno seguente. Se si desidera determinare correttamente il numero di ore dall'ora A e l'ora B, è necessario prima tradurre ciascuno dei rispettivi equivalenti UTC prima di calcolare TimeSpan.

Questo è coperto da un post sul blog che ho scritto ciò spiega ulteriormente TimeSpan e include un collegamento a un articolo MS ancora più esteso sull'argomento.

* Chiarimento: in entrambi i casi verrà memorizzata l'ora corrente. Se dovessi caricare due variabili uno tramite DateTime.Now () e l'altro tramite DateTime.UtcNow () la differenza di differenza tra i due TimeSpan sarebbe millisecondi, non ore supponendo che ti trovi in ​​una fascia oraria lontana da GMT. Come indicato di seguito, la stampa dei propri valori di stringa mostrerebbe stringhe diverse.


25
2017-09-16 20:22



Si noti anche la differenza di prestazioni; DateTime.UtcNow è da qualche parte circa 30 volte più veloce di DateTime.Ora, perché internamente DateTime.Now sta eseguendo molti aggiustamenti dei fusi orari (puoi facilmente verificarlo con Reflector).

Quindi non utilizzare DateTime.Ora per misurazioni relative del tempo.


24
2018-02-21 13:16



Questa è una buona domanda. Lo sto facendo rivivere per dare un po 'più di dettaglio su come .Net si comporta con diversi valori di "tipo". Come sottolinea @Jan Zich, è in realtà una proprietà di importanza critica e viene impostata in modo diverso a seconda che si utilizzi Now o UtcNow.

Internamente la data viene memorizzata come "Ticks" che (contrariamente alla risposta di @Carl Camera) è diversa a seconda se usi Now o UtcNow.

DateTime.UtcNow si comporta come le altre lingue. Imposta le zecche su un valore basato su GMT. Imposta anche "Tipo" su "Utc".

DateTime.Ora modifica il valore di zecche a cosa sarebbe se fosse il tuo momento della giornata nel fuso orario GMT. Imposta anche "Tipo" su "Locale".

Se sei indietro di 6 ore (GMT-6), riceverai l'ora GMT da 6 ore. .Net in realtà ignora "Kind" e tratta questa volta come se fosse 6 ore fa, anche se dovrebbe essere "now". Questo si rompe ancora di più se si crea un'istanza DateTime, quindi si modifica il fuso orario e si tenta di utilizzarlo.

Le istanze DateTime con diversi valori "Tipo" NON sono compatibili.

Diamo un'occhiata ad un codice ...

    DateTime utc = DateTime.UtcNow;
    DateTime now = DateTime.Now;
    Debug.Log (utc + " " + utc.Kind);  // 05/20/2015 17:19:27 Utc
    Debug.Log (now + " " + now.Kind);  // 05/20/2015 10:19:27 Local

    Debug.Log (utc.Ticks);  // 635677391678617830
    Debug.Log (now.Ticks);  // 635677139678617840

    now = now.AddHours(1);
    TimeSpan diff = utc - now;
    Debug.Log (diff);  // 05:59:59.9999990

    Debug.Log (utc <  now);  // false
    Debug.Log (utc == now);  // false
    Debug.Log (utc >  now);  // true

    Debug.Log (utc.ToUniversalTime() <  now.ToUniversalTime());  // true
    Debug.Log (utc.ToUniversalTime() == now.ToUniversalTime());  // false
    Debug.Log (utc.ToUniversalTime() >  now.ToUniversalTime());  // false
    Debug.Log (utc.ToUniversalTime() -  now.ToUniversalTime());  // -01:00:00.0000010

Come puoi vedere qui, le comparazioni e le funzioni matematiche non si convertono automaticamente in orari compatibili. Il tempo previsto avrebbe dovuto essere quasi un'ora, ma invece era quasi 6. "utc <now" avrebbe dovuto essere vero (ho persino aggiunto un'ora per essere sicuro), ma era ancora falso.

Puoi anche vedere il "work around" che è semplicemente convertire in universal time ovunque che "Kind" non sia lo stesso.

La mia risposta diretta alla domanda è in accordo con la raccomandazione della risposta accettata su quando utilizzare ciascuno di essi. Dovresti sempre provare lavorare con oggetti DateTime che hanno Kind = Utc, tranne durante i / o (visualizzazione e analisi). Questo significa che dovresti quasi sempre usare DateTime.UtcNow, tranne i casi in cui stai creando l'oggetto solo per visualizzarlo, e scartalo subito.


13
2018-05-08 21:09



DateTime non ha idea di quali siano i fusi orari. Presuppone sempre che tu sia al tuo orario locale. utcnow significa solo "Sottrai il mio fuso orario dal momento".

Se si desidera utilizzare date in base al fuso orario, utilizzare DateTimeOffset, che rappresenta una data / ora con un fuso orario. Dovevo imparare questo nel modo più duro.


6
2017-09-15 11:05



Solo una piccola aggiunta ai punti fatti sopra: la struttura DateTime contiene anche un campo poco conosciuto chiamato Genere (almeno, non lo sapevo da molto tempo). È fondamentalmente solo una bandiera che indica se l'ora è locale o UTC; non specifica l'offset reale da UTC per le ore locali. Oltre al fatto che indica con quali intenzioni è stato costruito lo stativo, influenza anche il modo in cui i metodi ToUniversalTime () e ToLocalTime () lavoro.


4
2018-04-18 00:12