it-swarm-eu.dev

DateTime.Now vs. DateTime.UtcNow

Ich habe mich gefragt, was genau die Prinzipien für die Funktionsweise der beiden Eigenschaften sind. Ich weiß, dass die zweite universell ist und sich im Grunde nicht mit Zeitzonen befasst, aber kann jemand im Detail erklären, wie sie funktionieren und welche in welchem ​​Szenario verwendet werden sollten?

197
Slavo

DateTime.UtcNow zeigt Ihnen das Datum und die Uhrzeit wie in der koordinierten Weltzeit an, die auch als Greenwich Mean Time-Zeitzone bezeichnet wird - im Grunde wie in London, England, aber nicht während des Sommers. DateTime.Now gibt das Datum und die Uhrzeit so an, wie es jemandem in Ihrem aktuellen Gebietsschema erscheinen würde.

Ich würde empfehlen, DateTime.Now Wenn Sie einem Menschen ein Datum anzeigen - auf diese Weise fühlen sie sich mit dem Wert, den sie sehen, wohl -, ist dies etwas, das sie leicht mit dem vergleichen können, was sie auf ihrer Uhr oder Armbanduhr sehen. Verwenden DateTime.UtcNow Wenn Sie Daten speichern oder für spätere Berechnungen verwenden möchten (in einem Client-Server-Modell), werden Ihre Berechnungen nicht von Clients in unterschiedlichen Zeitzonen von Ihrem Server oder voneinander verwirrt.

311
Blair Conrad

Beachten Sie auch den Leistungsunterschied; DateTime.UtcNow ist ungefähr 30-mal schneller als DateTime.Now, da DateTime.Now intern viele Zeitzonenanpassungen vornimmt (Sie können dies problemlos mit Reflector überprüfen).

Verwenden Sie DateTime.Now nicht für relative Zeitmessungen.

29
Magnus Krisell

Ein in .NET zu verstehendes Hauptkonzept ist, dass jetzt jetzt alles ist Egal in welcher Zeitzone Sie sich auf der Erde befinden. Wenn Sie also eine Variable mit DateTime.Now oder DateTime.UtcNow laden, ist die Zuweisung identisch. * Ihr DateTime - Objekt weiß was Die Zeitzone, in der Sie sich befinden, wird unabhängig von der Zuordnung berücksichtigt.

Die Nützlichkeit von DateTime.UtcNow Ist nützlich, wenn Daten über die Grenzen der Sommerzeit berechnet werden. Das heißt, an Orten, die an der Sommerzeit teilnehmen, gibt es manchmal 25 Stunden von Mittag bis Mittag am folgenden Tag und manchmal 23 Stunden zwischen Mittag und Mittag am folgenden Tag. Wenn Sie die Anzahl der Stunden ab dem Zeitpunkt A und dem Zeitpunkt B korrekt bestimmen möchten, müssen Sie diese zunächst in ihre UTC-Äquivalente übersetzen, bevor Sie die TimeSpan berechnen.

Dies wird durch ein Blog-Beitrag, den ich geschrieben habe abgedeckt, das TimeSpan näher erläutert und einen Link zu einem noch umfangreicheren MS-Artikel zum Thema enthält.

* Erläuterung: In beiden Zuordnungen wird die aktuelle Uhrzeit gespeichert. Wenn Sie zwei Variablen über DateTime.Now() und die andere über DateTime.UtcNow() laden würden, wäre die Differenz TimeSpan zwischen den beiden Millisekunden, nicht Stunden, wenn Sie sich in einer Zeitzone befinden Stunden von GMT entfernt. Wie unten erwähnt, werden beim Ausdrucken der String - Werte unterschiedliche Zeichenfolgen angezeigt.

26
Carl Camera

Das ist eine gute Frage. Ich wiederhole es, um ein bisschen mehr Details darüber zu geben, wie .Net sich mit verschiedenen Kind Werten verhält. Wie @Jan Zich betont, handelt es sich tatsächlich um eine wichtige Eigenschaft, die je nachdem, ob Sie Now oder UtcNow verwenden, unterschiedlich festgelegt wird.

Intern wird das Datum als Ticks gespeichert, was (im Gegensatz zu @Carl Cameras Antwort) davon abhängt, ob Sie Now oder UtcNow verwenden.

DateTime.UtcNow Verhält sich wie andere Sprachen. Es setzt Ticks auf einen GMT-basierten Wert. Es setzt auch Kind auf Utc.

DateTime.Now Ändert den Wert von Ticks auf was wäre, wenn es Ihre Tageszeit in der GMT-Zeitzone wäre. Es setzt auch Kind auf Local.

Wenn Sie 6 Stunden hinterher sind (GMT-6), erhalten Sie die GMT-Zeit von vor 6 Stunden. .Net ignoriert Kind und behandelt dieses Mal, als wäre es 6 Stunden her, obwohl es "jetzt" sein soll. Dies macht noch schlimmer, wenn Sie eine DateTime -Instanz erstellen, dann Ihre Zeitzone ändern und versuchen, sie zu verwenden.

DateTime-Instanzen mit unterschiedlichen 'Kind'-Werten sind NICHT kompatibel.

Schauen wir uns einen Code an ...

    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

Wie Sie hier sehen können, werden Vergleiche und mathematische Funktionen nicht automatisch in kompatible Zeiten konvertiert. Das Timespan sollte fast eine Stunde betragen, war aber stattdessen fast 6. "utc <now" hätte wahr sein sollen (ich habe sogar eine Stunde hinzugefügt, um sicher zu sein), war aber immer noch falsch.

Sie können auch die Umgehung sehen, die darin besteht, einfach überall dort in die Weltzeit umzurechnen, wo Kind nicht identisch ist.

Meine direkte Antwort auf die Frage stimmt mit der Empfehlung der akzeptierten Antwort überein, wann sie verwendet werden soll. Sie sollten immer versuchen mit DateTime Objekten arbeiten, die Kind=Utc Haben, außer während der Ein-/Ausgabe (Anzeigen und Parsen). Dies bedeutet, dass Sie fast immer DateTime.UtcNow Verwenden sollten, mit Ausnahme der Fälle, in denen Sie das Objekt nur zum Anzeigen erstellen und sofort verwerfen.

15
Ted Bigham

DateTime hat keine Ahnung, was Zeitzonen sind. Es wird immer davon ausgegangen, dass Sie zu Ihrer Ortszeit sind. UtcNow bedeutet nur "Subtrahiere meine Zeitzone von der Zeit".

Wenn Sie zeitzonenbezogene Daten verwenden möchten, verwenden Sie DateTimeOffset, das ein Datum/eine Uhrzeit mit einer Zeitzone darstellt. Das musste ich auf die harte Tour lernen.

6

Die "einfache" Antwort auf die Frage lautet:

DateTime.Now gibt einen DateTime Wert zurück, der die aktuelle Systemzeit darstellt (in welcher Zeitzone auch immer das System ausgeführt wird). Die Eigenschaft DateTime.Kind lautet DateTimeKind.Local

DateTime.UtcNow gibt einen DateTime Wert zurück, der die aktuelle koordinierte Weltzeit (UTC) darstellt, die unabhängig von der Zeitzone des Systems gleich ist. Die Eigenschaft DateTime.Kind lautet DateTimeKind.Utc

4
PapillonUK

Nur eine kleine Ergänzung zu den oben genannten Punkten: Die DateTime-Struktur enthält auch ein wenig bekanntes Feld namens Kind (zumindest wusste ich lange nichts darüber). Es ist im Grunde nur ein Flag, das angibt, ob die Zeit lokal oder UTC ist. Der tatsächliche Versatz von UTC für Ortszeiten wird nicht angegeben. Neben der Tatsache, dass es anzeigt, mit welchen Absichten der Stuct konstruiert wurde, beeinflusst es auch die Funktionsweise der Methoden ToUniversalTime () und ToLocalTime () .

4
Jan Zich
2
Sorin Comanescu

DateTime.UtcNow ist eine kontinuierliche, einwertige Zeitskala, wohingegen DateTime.Now keine kontinuierliche oder einwertige Zeitskala ist. Der Hauptgrund ist die Sommerzeit, die für UTC nicht gilt. UTC springt also nie eine Stunde vor oder zurück, wohingegen die Ortszeit (DateTime.Now) dies tut. Und wenn es rückwärts springt, tritt der gleiche Zeitwert zweimal auf.

1
user1315023

DateTime.UtcNow ist eine universelle Zeitskala ohne Sommerzeit. UTC ändert sich also nie aufgrund der Sommerzeit.

DateTime.Now ist jedoch nicht fortlaufend oder einwertig, da es sich entsprechend der Sommerzeit ändert. Was bedeutet, dass DateTime.Now, der gleiche Zeitwert zweimal auftreten kann und Kunden in einem verwirrten Zustand zurücklässt.

1
ChaiVan

Wenn Sie eine Ortszeit für den Computer benötigen, auf dem Ihre Anwendung ausgeführt wird (z. B. MESZ für Europa), verwenden Sie "Jetzt". Wenn Sie eine Weltzeit wollen - UtcNow. Es ist nur eine Frage Ihrer Präferenzen - wahrscheinlich möchten Sie eine lokale Website/Standalone-Anwendung erstellen, die die Zeit verwendet, die der Benutzer verwendet - und die von seiner/ihrer Zeitzoneneinstellung beeinflusst wird - DateTime.Now.

Denken Sie daran, dass es sich bei einer Website um die Zeitzoneneinstellung des Servers handelt. Wenn Sie also die Zeit für den Benutzer anzeigen, geben Sie entweder seine bevorzugte Zeitzone an und verschieben Sie die Zeit (speichern Sie dann die UTC-Zeit in der Datenbank und ändern Sie sie) oder geben Sie die UTC-Zeit an. Wenn Sie dies vergessen, kann der Benutzer Folgendes sehen: vor 3 Minuten gepostet und dann eine Zeit in der Zukunft in der Nähe :)

0
kender