72 Stimmen

Wie funktioniert DateTime.ToUniversalTime()?

Wie erfolgt die Umstellung auf UTC vom Standard DateTime Format funktionieren?

Genauer gesagt, wenn ich eine DateTime Objekt in einer Zeitzone und wechseln dann in eine andere Zeitzone und führen ToUniversalTime() Woher weiß es, dass die Umrechnung korrekt erfolgt ist und die Zeit noch genau angezeigt wird?

84voto

womp Punkte 113535

Es gibt keine implizite Zeitzone, die mit einer DateTime Gegenstand. Wenn Sie ToUniversalTime() verwenden, wird die Zeitzone des Kontexts verwendet, in dem der Code läuft.

Wenn ich zum Beispiel eine DateTime von der Epoche des 1.1.1970 an, erhalte ich das gleiche DateTime Objekt, egal wo auf der Welt ich bin.

Wenn ich die ToUniversalTime() wenn ich den Code in Greenwich ausführe, dann erhalte ich dieselbe Zeit. Wenn ich es mache, während ich in Vancouver lebe, erhalte ich eine Verschiebung DateTime Objekt von -8 Stunden.

Deshalb ist es wichtig, zeitbezogene Informationen in Ihrer Datenbank als UTC-Zeiten zu speichern, wenn Sie irgendeine Art von Datumsumwandlung oder Lokalisierung vornehmen müssen. Denken Sie daran, wenn Ihre Codebasis auf einen Server in einer anderen Zeitzone verlegt wird ;)

Edit: Anmerkung zu Joels Antwort - DateTime Objekte sind standardmäßig typisiert als DateTimeKind.Local . Wenn Sie ein Datum parsen und es als DateTimeKind.Utc dann ToUniversalTime() führt keine Konvertierung durch.

Und hier ist ein Artikel über "Bewährte Praktiken bei der Codierung mit Datumszeiten" und einen Artikel über Konvertierung von DateTimes mit .Net .

1 Stimmen

Nein. Die aktuelle Zeit spielt keine Rolle. Sie interessiert sich für die Zeitzone des lokalen Systems.

15 Stimmen

Sie wollen nicht 何時も zeitbezogene Informationen in UTC speichern. Es kommt ganz darauf an, was diese Informationen wirklich sind. Zeitpunkte können in der Regel in UTC dargestellt werden, aber nicht alles ist ein Zeitpunkt. Ich sitze zum Beispiel im Zug um 17:18 Uhr aus Paddington. Es ist sinnvoll, dies als "17:18 Europa/London" und nicht als "16:18 UTC" zu speichern, denn wenn die Uhren zurückgestellt werden, wird die . die Zeit bleibt gleich.

0 Stimmen

Kann ich sie in einer Linq-Abfrage verwenden?

38voto

Jon Skeet Punkte 1325502

Erstens prüft sie, ob die Kind der DateTime ist bereits als UTC bekannt. Ist dies der Fall, wird derselbe Wert zurückgegeben.

Andernfalls wird davon ausgegangen, dass es sich um eine lokale Zeit handelt, d. h. um eine lokale Zeit des Computers, auf dem das Programm läuft, und zwar in der Zeitzone, die der Computer verwendet hat, als er zum ersten Mal mit einer privaten Eigenschaft initialisiert wurde. Das bedeutet, wenn Sie die Zeitzone ändern nach Ihre Anwendung gestartet wurde, ist die Wahrscheinlichkeit groß, dass sie noch die alte Version verwendet.

Die Zeitzone enthält genügend Informationen, um eine Ortszeit in eine UTC-Zeit oder umgekehrt zu konvertieren, obwohl dies manchmal nicht eindeutig oder ungültig ist. (Es gibt Ortszeiten, die zweimal vorkommen, und Ortszeiten, die wegen der Sommerzeit nie vorkommen.) Die Regeln für die Behandlung dieser Fälle sind in die Dokumentation :

Wenn das Datum und die Uhrzeit insta eine mehrdeutige Zeit, nimmt diese Methode an dass es sich um eine Standardzeit handelt. (Eine mehrdeutige Zeit ist eine, die entweder [ ] Sommerzeit in der lokalen Zeitzone Zone zugeordnet werden kann.) Wenn der Wert der Datums- und Zeitinstanz Wert eine ungültige Zeit ist, subtrahiert diese Methode einfach die lokale Zeit von der dem UTC-Offset der lokalen Zeitzone, um UTC zurückzugeben. (Eine ungültige Zeit ist eine die nicht existiert, weil die Anwendung der Sommerzeit Anpassungsregeln nicht existiert.)

Der zurückgegebene Wert hat eine Kind von DateTimeKind.Utc Wenn Sie also anrufen ToUniveralTime dann wird der Versatz nicht mehr angewendet. (Dies ist eine enorme Verbesserung gegenüber .NET 1.1!)

Wenn Sie eine nicht-lokale Zeitzone wünschen, sollten Sie TimeZoneInfo die in .NET 3.5 eingeführt wurde (für frühere Versionen gibt es Hacking-Lösungen, aber die sind nicht schön). Um einen Moment in der Zeit darzustellen, sollten Sie die Verwendung von DateTimeOffset die in .NET 2.0SP1, .NET3.0SP1 und .NET 3.5 eingeführt wurde. Allerdings ist damit immer noch keine tatsächliche Zeitzone verbunden, sondern nur eine Abweichung von der UTC. Das bedeutet, dass Sie nicht wissen, wie die Ortszeit beispielsweise eine Stunde später sein wird - die Sommerzeitregeln können zwischen den Zeitzonen variieren, die zufällig denselben Versatz für diesen bestimmten Zeitpunkt verwenden. TimeZoneInfo ist so konzipiert, dass historische und künftige Regeln berücksichtigt werden, im Gegensatz zu TimeZone was etwas vereinfacht ist.

Grundsätzlich ist die Unterstützung in .NET 3.5 viel besser als früher, lässt aber immer noch etwas zu wünschen übrig, was die korrekte Kalenderarithmetik angeht. Hat jemand Lust zu portieren Joda Zeit zu .NET? ;)

7voto

Joel Coehoorn Punkte 377088

Was @womp sagte mit dem Zusatz, dass es die DateTime-Eigenschaft Kind prüft, um zu sehen, ob sie möglicherweise bereits ein UTC-Datum sein.

0 Stimmen

Gutes Argument. Wenn der Typ nicht explizit festgelegt ist, wird eine lokale Zeit angenommen, und der Aufruf von ToUniversalTime() setzt den Typ auf Universal am neuen Datum.

0 Stimmen

Es ist erwähnenswert, dass SQL Server das Kind nicht speichert ( stackoverflow.com/questions/823313/ ). Wenn Sie also ein UTC-Datum auf einem US-Server speichern, wird angenommen, dass es lokal ist.

4voto

DateTime.ToUniversalTime entfernt den Zeitzonen-Offset der lokalen Zeitzone, um eine DateTime auf UTC zu normalisieren. Wenn Sie dann DateTime.ToLocalTime auf den normalisierten Wert in einer anderen Zeitzone anwenden, wird der Zeitzonen-Offset dieser Zeitzone zu dem normalisierten Wert hinzugefügt, um eine korrekte Darstellung in dieser Zeitzone zu gewährleisten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X