Wie funktioniert DateTime.ToUniversalTime () funktioniert?
Frage
Wie funktioniert die Umstellung auf UTC vom Standard DateTime
Format Arbeit?
Genauer gesagt, wenn ich ein DateTime
Objekt in einer Zeitzone erstellen und wechseln Sie dann zu einer anderen Zeitzone und führe ToUniversalTime()
darauf, wie es weiß die Umwandlung richtig gemacht wurde und dass die Zeit noch genau dargestellt?
Lösung
Es gibt keine implizite Zeitzone zu einem DateTime
Objekt angebracht. Wenn Sie ToUniversalTime()
darauf laufen, es verwendet die Zeitzone des Kontextes, dass der Code in ausgeführt wird.
Zum Beispiel, wenn ich eine DateTime
aus der Epoche der 1.1.1970 schaffen, es gibt mir das gleiche DateTime
Objekt, egal wo in der Welt ich bin.
Wenn ich ToUniversalTime()
darauf laufen, wenn ich den Code in Greenwich renne, dann bekomme ich die gleiche Zeit. Wenn ich es tun, während ich in Vancouver leben, dann erhalte ich eine Offset DateTime
Objekt von -8 Stunden.
Aus diesem Grunde ist es wichtig, zeitbezogene Informationen in Ihrer Datenbank als UTC-Zeiten zu speichern, wenn Sie jede Art von Datumsumstellung oder Lokalisierung tun müssen. Überlegen Sie, ob Ihre Code-Basis zu einer Servereinrichtung in einer anderen Zeitzone bewegt wurde;)
Edit: Notiz von Joel Antwort - DateTime
Objekte sind standardmäßig als DateTimeKind.Local
eingegeben haben. Wenn Sie ein Datum analysieren und sie als DateTimeKind.Utc
gesetzt ist, dann führt ToUniversalTime()
keine Konvertierung.
Und hier ist ein Artikel über "Best Practices Codierung mit Datum Zeit" , und ein Artikel über Datetime mit .Net konvertieren.
Andere Tipps
Zunächst wird geprüft, ob die Kind
der DateTime
bekannt ist UTC schon zu sein. Wenn ja, gibt sie den gleichen Wert haben.
Ansonsten ist es angenommen, eine lokale Zeit zu sein - das ist lokal auf dem Computer, auf es läuft, und insbesondere in der Zeitzone, die der Computer wurde mit, wenn einige Privateigentum wurde zuerst gemächlich initialisiert. Das heißt, wenn Sie die Zeitzone ändern nach Ihrer Anwendung gestartet wurde, gibt es eine gute Chance, es wird immer noch die alten werden.
Die Zeitzone enthält genügend Informationen, eine lokale Zeit zu einer UTC-Zeit oder umgekehrt zu konvertieren, obwohl es Zeiten gibt, dass das ist zweideutig oder ungültig. (Es gibt lokale Zeiten, die zweimal und Ortszeit auftreten, die nie wegen Sommerzeit auftreten.) Die Regeln für den Umgang mit diesen Fällen sind angegeben in die Dokumentation :
Wenn das Datum und die Uhrzeit Instanz Wert eine mehrdeutige Zeit, dieses Verfahren nimmt dass es sich um eine Standardzeit. (Ein mehrdeutige Zeit ist eine, die Karte kann entweder zu einer Standardzeit oder zu einem Sommerzeit in der Ortszeit Zone) Wenn das Datum und die Uhrzeit Instanz Wert ist eine ungültige Zeit, diese Methode einfach subtrahiert die lokale Zeit von die lokale UTC Zeitzone versetzt Rückkehr UTC. (Eine ungültige Zeit ist ein dass ist nicht vorhanden, da der Anwendung der Sommerzeit Anpassungsregeln.)
Der Rückgabewert wird eine Kind
von DateTimeKind.Utc
hat, wenn Sie also ToUniveralTime
rufen, dass es den Versatz wieder nicht gelten. (Dies ist eine große Verbesserung gegenüber .NET 1.1!)
Wenn Sie eine nicht-lokale Zeitzone wollen, sollten Sie TimeZoneInfo
, die in .NET 3.5 eingeführt wurde (es gibt hacky Lösungen für frühere Versionen, aber sie sind nicht schön). Um einen Zeitpunkt darstellen, sollten Sie mit DateTimeOffset
die wurde in .NET 2.0SP1, .NET3.0SP1 und .NET 3.5 eingeführt. Allerdings ist das noch nicht eine tatsächliche Zeitzone mit ihm verbunden hat - nur einen Offset von UTC. Das bedeutet, dass Sie nicht wissen, was Ortszeit eine Stunde später sein wird, zum Beispiel - die DST-Regeln zwischen den Zeitzonen variieren können, die das gleiche für diesen speziellen Augenblick Offset zu benutzen passiert ist. TimeZoneInfo
ist so konzipiert, historische und zukünftige Regeln zu berücksichtigen, im Gegensatz zu TimeZone
, die etwas simpel ist.
Grundsätzlich ist die Unterstützung in .NET 3.5 ist viel besser, als es war, lässt aber immer noch etwas für die richtige Kalender Arithmetik zu wünschen übrig. Wer Lust Portierungs Joda Zeit auf .NET? ;)
Was @womp sagte , mit dem Zusatz, dass es die Datetime der Kind-Eigenschaft überprüft, ob es vielleicht bereits ein UTC-Datum sein.
DateTime.ToUniversalTime entfernt die Zeitzone des lokalen Zeitzone versetzt, um einen Datetime UTC zu normalisieren. Wenn Sie dann DateTime.ToLocalTime auf dem normalisierten Wert in einer anderen Zeitzone verwenden, die Zeitzone dieser Zeitzone versetzt wird für die korrekte Darstellung in dieser Zeitzone auf den normalisierten Wert hinzugefügt werden.