it-swarm.it

DateTime.Now vs. DateTime.UtcNow

Mi chiedevo quali sono esattamente i principi di 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?

197
Slavo

DateTime.UtcNow ti dice la data e l'ora come sarebbe nel tempo coordinato universale, che è anche chiamato il fuso orario di Greenwich - sostanzialmente come sarebbe se tu fossi a Londra, in Inghilterra, ma non durante l'estate. DateTime.Now fornisce la data e l'ora come apparirebbero a qualcuno nella tua locale attuale.

Consiglierei di usare DateTime.Now ogni volta che mostri una data a un essere umano - in questo modo si sentono a proprio agio con il valore che vedono - è qualcosa che possono facilmente confrontare con ciò che vedono sul loro orologio o orologio. Uso DateTime.UtcNow quando desideri memorizzare le date o usarle per calcoli successivi in ​​quel modo (in un modello client-server) i tuoi calcoli non vengono confusi dai client in fusi orari diversi dal tuo server o l'uno dall'altro.

311
Blair Conrad

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

Se non usi Utc, devi conosci il fuso orario della persona a cui stai visualizzando date e orari - altrimenti dirai loro che è successo qualcosa a 3 PM nel sistema o ora del server, quando è realmente accaduto alle 5 PM dove risiedono.

Usiamo DateTime.UtcNow Perché abbiamo un pubblico web globale e perché preferirei non tormentare tutti gli utenti per compilare un modulo che indica in quale fuso orario vivono.

Visualizziamo anche i tempi relativi (2 ore fa, 1 giorno fa, ecc.) Fino a quando il post non invecchierà abbastanza che il tempo sia "lo stesso" indipendentemente da dove vivi sulla Terra.

80
Jeff Atwood

Notare anche la differenza di prestazioni; DateTime.UtcNow è circa 30 volte più veloce di DateTime.Now, perché internamente DateTime.Now sta effettuando molte regolazioni del fuso orario (è possibile verificarlo facilmente con Reflector).

Quindi non usare DateTime.Now per le misurazioni del tempo relative.

29
Magnus Krisell

Un concetto principale da capire in .NET è che ora è ora tutto sulla terra, indipendentemente dal fuso orario in cui ti trovi. Quindi, se carichi una variabile con DateTime.Now o DateTime.UtcNow - l'assegnazione è identica. * Il tuo oggetto DateTime sa cosa fuso orario in cui ci si trova e ne tiene conto indipendentemente dall'assegnazione.

L'utilità di DateTime.UtcNow È utile quando si calcolano le date oltre i confini dell'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 tra l'ora A e l'ora B, è necessario prima tradurre ciascuno in equivalenti UTC prima di calcolare TimeSpan.

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

* Chiarimento: entrambi i compiti memorizzeranno l'ora corrente. Se dovessi caricare due variabili una tramite DateTime.Now() e l'altra tramite DateTime.UtcNow() la differenza TimeSpan tra i due sarebbe millisecondi, non le ore supponendo che ti trovi in ​​un fuso orario ore di distanza dal GMT. Come indicato di seguito, la stampa dei valori String visualizzerà stringhe diverse.

26
Carl Camera

Questa è una buona domanda Lo sto rianimando per dare un po 'più di dettagli su come .Net si comporta con diversi valori Kind. Come sottolinea @Jan Zich, in realtà è una proprietà di fondamentale importanza e viene impostata in modo diverso a seconda che si usi Now o UtcNow.

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

DateTime.UtcNow si comporta come altre lingue. Imposta Ticks su un valore basato su GMT. Imposta anche Kind su Utc.

DateTime.Now modifica il valore Ticks in quale sarebbe se fosse la tua ora del giorno nel fuso orario GMT. Imposta anche Kind su Local.

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

Le istanze di DateTime con valori 'Kind' diversi NON sono compatibili.

Diamo un'occhiata ad un po 'di 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, i confronti e le funzioni matematiche non si convertono automaticamente in tempi compatibili. Il Timespan avrebbe dovuto essere quasi un'ora, ma invece era quasi 6. "utc <now" avrebbe dovuto essere vero (ho anche aggiunto un'ora per essere sicuro), ma era ancora falso.

Puoi anche vedere il 'aggirare' che è semplicemente convertire in tempo universale ovunque che Kind non sia lo stesso.

La mia risposta diretta alla domanda concorda con la raccomandazione della risposta accettata su quando utilizzarla. Dovresti sempre provare a lavorare con DateTime oggetti che hanno Kind=Utc, tranne durante l'I/O (visualizzazione e analisi). Questo significa che dovresti quasi sempre usare DateTime.UtcNow, ad eccezione dei casi in cui stai creando l'oggetto solo per visualizzarlo e scartalo immediatamente.

15
Ted Bigham

DateTime non ha idea di quali fusi orari siano. Presuppone sempre che tu sia all'ora locale. UtcNow significa solo "Sottrai il mio fuso orario dall'ora".

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

6
Omer van Kloeten

La "semplice" risposta alla domanda è:

DateTime.Now restituisce un valore DateTime che rappresenta l'ora corrente del sistema (in qualunque fuso orario il sistema è in esecuzione). La proprietà DateTime.Kind sarà DateTimeKind.Local

DateTime.UtcNow restituisce un valore DateTime che rappresenta l'ora coordinata universale corrente (aka UTC) che sarà la stessa indipendentemente dal fuso orario del sistema. La proprietà DateTime.Kind sarà DateTimeKind.Utc

4
PapillonUK

Solo una piccola aggiunta ai punti sopra menzionati: la struttura DateTime contiene anche un campo poco noto chiamato Kind (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 l'ora locale. Oltre al fatto che indica con quali intenzioni è stata costruita la struttura, influenza anche il modo in cui funzionano i metodi ToUniversalTime () e ToLocalTime () .

4
Jan Zich
2
Sorin Comanescu

DateTime.UtcNow è una scala temporale continua a valore singolo, mentre DateTime.Now non è continuo o a valore singolo. Il motivo principale è l'ora legale, che non si applica all'ora UTC. Quindi UTC non salta mai avanti o indietro di un'ora, mentre l'ora locale (DateTime.Now) lo fa. E quando salta all'indietro, lo stesso valore temporale si verifica due volte.

1
user1315023

DateTime.UtcNow è una scala di tempo universale che omette l'ora legale. Quindi UTC non cambia mai a causa dell'ora legale.

Tuttavia, DateTime.Now non è continuo o a valore singolo perché cambia in base all'ora legale. Il che significa DateTime.Now, lo stesso valore temporale può verificarsi due volte lasciando i clienti in uno stato confuso.

1
ChaiVan

Quando è necessaria l'ora locale per il computer su cui viene eseguita l'applicazione (come CEST per l'Europa), utilizzare Now. Se vuoi un tempo universale - UtcNow. È solo una questione di preferenze - probabilmente creando un sito Web locale/un'applicazione autonoma che vorresti usare il tempo che l'utente ha - così influenzato dalle sue impostazioni del fuso orario - DateTime.Now.

Ricorda, per un sito Web è l'impostazione del fuso orario del server. Quindi, se stai visualizzando il tempo per l'utente, ottieni il suo fuso orario preferito e sposta il tempo (basta salvare il tempo Utc nel database e modificarlo) o specificare il suo UTC. Se ti dimentichi di farlo, l'utente può vedere qualcosa di simile: pubblicato 3 meno fa e poi un tempo in futuro vicino ad esso :)

0
kender