c# - datetimeoffset to datetime




DateTime vs DateTimeOffset (6)

DateTime kann nur zwei verschiedene Zeiten speichern, die lokale Zeit und UTC. Die Eigenschaft Kind gibt an, welche.

DateTimeOffset erweitert dies, indem es lokale Zeiten von überall auf der Welt speichern kann. Es speichert auch den Versatz zwischen dieser lokalen Zeit und UTC. Beachten Sie, dass DateTime dies nicht tun kann, es sei denn, Sie würden Ihrer Klasse ein zusätzliches Mitglied hinzufügen, um diese UTC-Verschiebung zu speichern. Oder arbeite immer nur mit UTC. Was an sich schon eine gute Idee ist.

Gegenwärtig haben wir eine Standardmethode, um mit .Net DateTimes in einer TimeZone-bewussten Weise umzugehen: Wann immer wir eine DateTime erzeugen, tun wir dies in UTC (zB mit DateTime.UtcNow), und wann immer wir eine anzeigen, konvertieren wir zurück von UTC in die des Benutzers Ortszeit.

Das funktioniert gut, aber ich habe über DateTimeOffset gelesen und wie es die lokale und UTC-Zeit im Objekt selbst erfasst. Die Frage ist also, was wären die Vorteile der Verwendung von DateTimeOffset gegenüber dem, was wir bereits getan haben?


Der wichtigste Unterschied ist, dass DateTime keine Zeitzoneninformationen speichert, während DateTimeOffset dies tut.

Obwohl DateTime zwischen UTC und Local unterscheidet, ist kein expliziter Zeitzonenoffset zugeordnet. Wenn Sie eine Art von Serialisierung oder Konvertierung durchführen, wird die Zeitzone des Servers verwendet. Selbst wenn Sie manuell eine lokale Zeit erstellen, indem Sie Minuten zum Versetzen einer UTC-Zeit hinzufügen, können Sie im Serialisierungsschritt immer noch ein Bit erhalten, da (aufgrund des Fehlens eines expliziten Offsets in DateTime) der Zeitzonen-Offset des Servers verwendet wird.

Wenn Sie beispielsweise einen DateTime-Wert mit Kind = Local unter Verwendung von Json.Net und einem ISO-Datumsformat serialisieren, erhalten Sie eine Zeichenfolge wie 2015-08-05T07:00:00-04 . Beachten Sie, dass der letzte Teil (-04) nichts mit Ihrer DateTime oder einem Offset zu tun hat, den Sie zur Berechnung verwendet haben ... es ist nur der Zeitzonen-Offset des Servers.

In der Zwischenzeit enthält DateTimeOffset explizit den Offset. Es enthält möglicherweise nicht den Namen der Zeitzone, aber zumindest enthält es den Offset, und wenn Sie es serialisieren, erhalten Sie den explizit eingeschlossenen Offset in Ihrem Wert anstelle dessen, was die lokale Zeit des Servers gerade ist.


Die meisten Antworten sind gut, aber ich dachte über weitere Links von MSDN für weitere Informationen nach


Ein Hauptunterschied besteht darin, dass DateTimeOffset in Verbindung mit DateTimeOffset verwendet werden kann, um in lokale Zeiten in anderen Zeitzonen als dem aktuellen zu konvertieren.

Dies ist nützlich bei einer Serveranwendung (zB ASP.NET), auf die Benutzer in verschiedenen Zeitzonen zugreifen.


Von Microsoft:

Diese Verwendungen für DateTimeOffset-Werte sind wesentlich häufiger als für DateTime-Werte. Daher sollte DateTimeOffset als Standarddatum und -uhrzeit für die Anwendungsentwicklung gelten.

Quelle: "Auswählen zwischen DateTime, DateTimeOffset, TimeSpan und TimeZoneInfo" , MSDN

Wir verwenden DateTimeOffset für fast alles, da unsere Anwendung bestimmte Zeitpunkte behandelt (z. B. wenn ein Datensatz erstellt / aktualisiert wurde). Als Randnotiz verwenden wir auch DATETIMEOFFSET in SQL Server 2008.

Ich sehe DateTime als nützlich, wenn Sie nur mit Daten, nur mit Zeiten oder mit einem generischen Sinn umgehen wollen. Wenn Sie beispielsweise einen Alarm haben, den Sie jeden Tag um 7 Uhr morgens ausschalten möchten, können Sie ihn in DateTime mit einem DateTimeKind von DateTimeKind speichern, da er unabhängig von der Sommerzeit um 7 Uhr morgens ausgehen soll. Wenn Sie jedoch die Historie von DateTimeOffset möchten, verwenden Sie DateTimeOffset .

DateTimeOffset Sie vorsichtig, wenn Sie eine Mischung aus DateTimeOffset und DateTime insbesondere beim Zuweisen und Vergleichen zwischen den Typen. Vergleichen Sie außerdem DateTime Instanzen, die das gleiche DateTimeKind sind, nur, da DateTime beim Vergleichen den Zeitzonen-Offset ignoriert.


DateTimeOffset ist eine Darstellung der momentanen Zeit (auch als absolute Zeit bekannt ). Damit meine ich einen für alle universellen Zeitpunkt (ohne Schaltsekunden oder die relativistischen Effekte der Zeitdilatation ). Eine andere Möglichkeit zur Darstellung der momentanen Zeit ist eine DateTime wobei .Kind ist.

Dies unterscheidet sich von der Kalenderzeit (auch bürgerliche Zeit genannt ), die eine Position in einem Kalender darstellt, und es gibt viele verschiedene Kalender auf der ganzen Welt. Wir nennen diese Kalender Zeitzonen . Die Kalenderzeit wird durch DateTime wobei .Kind DateTimeKind.Unspecified oder DateTimeKind.Local . Und .Local ist nur in Szenarien sinnvoll, in denen Sie implizit verstehen, wo der Computer positioniert ist, der das Ergebnis verwendet. (Zum Beispiel die Arbeitsstation eines Benutzers)

Warum also DateTimeOffset statt UTC DateTime ? Es geht um die Perspektive. Lassen Sie uns eine Analogie verwenden - wir geben vor, Fotografen zu sein.

Stellen Sie sich vor, Sie stehen auf einer Kalender-Timeline und zeigen eine Kamera auf eine Person auf der momentanen Zeitlinie, die vor Ihnen liegt. Sie richten Ihre Kamera nach den Regeln Ihrer Zeitzone aus, die sich aufgrund von Sommerzeit oder aufgrund anderer Änderungen an der gesetzlichen Definition Ihrer Zeitzone periodisch ändern. (Sie haben keine ruhige Hand, Ihre Kamera ist zittrig.)

Die Person, die auf dem Foto steht, würde den Winkel sehen, aus dem Ihre Kamera stammt. Wenn andere Bilder machen, könnten sie aus verschiedenen Blickwinkeln sein. Dies ist der Offset Teil von DateTimeOffset .

Wenn Sie also Ihre Kamera mit "Eastern Time" beschriften, zeigen Sie manchmal von -5 und manchmal von -4. Es gibt Kameras auf der ganzen Welt, die alle verschiedene Dinge beschriftet haben und alle aus verschiedenen Blickwinkeln auf dieselbe momentane Zeitlinie zeigen. Einige von ihnen sind direkt neben (oder übereinander), so dass Sie nur wissen, dass der Offset nicht ausreicht, um zu bestimmen, mit welcher Zeitzone die Zeit verbunden ist.

Und was ist mit UTC? Nun, es ist die eine Kamera da draußen, die garantiert eine ruhige Hand hat. Es ist auf einem Stativ, fest im Boden verankert. Es wird nirgendwohin gehen. Wir nennen seinen Blickwinkel die Nullpunktverschiebung.

Also - was sagt uns diese Analogie? Es bietet einige intuitive Richtlinien.

  • Wenn Sie die Uhrzeit relativ zu einem bestimmten Ort darstellen, stellen Sie sie im Kalender mit einer DateTime . Seien Sie sicher, dass Sie niemals einen Kalender mit einem anderen verwechseln. Unspecified sollte deine Annahme sein. Local ist nur nützlich, DateTime.Now von DateTime.Now . Zum Beispiel könnte ich DateTime.Now bekommen und es in einer Datenbank speichern - aber wenn ich es DateTime.Now , muss ich annehmen, dass es Unspecified . Ich kann nicht darauf vertrauen, dass mein lokaler Kalender derselbe Kalender ist, aus dem er ursprünglich stammt.

  • Wenn Sie sich immer des Moments sicher sein müssen, stellen Sie sicher, dass Sie die momentane Zeit darstellen. Verwenden Sie DateTimeOffset , um es zu erzwingen, oder verwenden Sie UTC DateTime nach Konvention.

  • Wenn Sie einen Moment der momentanen Zeit verfolgen müssen, aber Sie möchten auch wissen, "Wie viel Uhr hat der Benutzer gedacht, dass es in ihrem lokalen Kalender war?" - Dann müssen Sie ein DateTimeOffset . Dies ist beispielsweise für Zeitmesssysteme sehr wichtig - sowohl für technische als auch für rechtliche Belange.

  • Wenn Sie jemals ein zuvor aufgenommenes DateTimeOffset ändern DateTimeOffset - Sie haben nicht genügend Informationen im Offset, um sicherzustellen, dass der neue Offset für den Benutzer immer noch relevant ist. Sie müssen auch eine Zeitzonen-ID speichern (denke - ich brauche den Namen der Kamera, damit ich ein neues Bild aufnehmen kann, auch wenn sich die Position geändert hat).

    Es sollte auch darauf hingewiesen werden, dass Noda Time dafür eine Darstellung namens " ZonedDateTime hat, während die .Net-Basisklassenbibliothek nichts Ähnliches hat. Sie müssten sowohl einen DateTimeOffset als auch einen TimeZoneInfo.Id Wert speichern.

  • Gelegentlich möchten Sie eine Kalenderzeit darstellen, die lokal für "wen auch immer" angezeigt wird. Zum Beispiel, wenn Sie definieren, was heute bedeutet. Heute ist immer Mitternacht bis Mitternacht, aber diese repräsentieren eine nahezu unendliche Anzahl überlappender Bereiche auf der momentanen Zeitlinie. (In der Praxis haben wir eine endliche Anzahl von Zeitzonen, aber Sie können Offsets bis zum Tick ausdrücken.) Stellen Sie in diesen Situationen sicher, dass Sie verstehen, wie Sie das "Wer fragt?" Stellen Sie eine Frage in eine einzelne Zeitzone, oder gehen Sie mit der Rückübersetzung in die momentane Zeit um.

Hier sind ein paar andere kleine DateTimeOffset über DateTimeOffset , die diese Analogie unterstützen, und einige Tipps, um es zu DateTimeOffset :

  • Wenn Sie zwei DateTimeOffset Werte vergleichen, werden sie vor dem Vergleich zunächst auf Null-Offset normalisiert. Mit anderen Worten, 2012-01-01T00:00:00+00:00 und 2012-01-01T02:00:00+02:00 beziehen sich auf denselben augenblicklichen Moment und sind daher äquivalent.

  • Wenn Sie einen DateTimeOffset und sich des .Offset sicher sein müssen, testen Sie sowohl den DateTimeOffset Wert als auch die .Offset Eigenschaft separat.

  • Im DateTime Framework ist eine einseitige implizite Konvertierung integriert, mit der Sie DateTime in einen DateTimeOffset Parameter oder eine DateTime Variable übergeben können. Wenn dies .Kind , ist das .Kind wichtig . Wenn Sie eine UTC-Art übergeben, wird sie mit einem Null-Offset ausgeführt, aber wenn Sie entweder .Local oder .Unspecified , wird davon ausgegangen, dass sie lokal ist . Das Framework sagt im Grunde: "Nun, du hast mich gebeten, die Kalenderzeit in die momentane Zeit zu konvertieren, aber ich habe keine Ahnung, woher das kommt, also werde ich nur den lokalen Kalender verwenden." Dies ist ein großer Fehler, wenn Sie auf einem Computer mit einer anderen Zeitzone eine nicht angegebene DateTime laden. (IMHO - das sollte eine Ausnahme werfen - aber das tut es nicht.)

Schamloser Stecker:

Viele Leute haben mit mir geteilt, dass sie diese Analogie als äußerst wertvoll empfinden, also habe ich sie in meinen Pluralsight-Kurs " Date and Time Fundamentals" aufgenommen . Sie finden eine Schritt-für-Schritt-Anleitung der Kameraanalogie im zweiten Modul "Context Matters" im Clip mit dem Titel "Calendar Time vs. Instantaneous Time".





datetimeoffset