DateTimeOffset
ist eine Darstellung von augenblickliche Zeit (auch bekannt als absolute Zeit ). Damit meine ich einen Moment in der Zeit, der für alle gilt (ohne Berücksichtigung von Schaltsekunden oder die relativistischen Effekte von Zeitdilatation ). Eine andere Möglichkeit, die momentane Zeit darzustellen, ist die Verwendung eines DateTime
wobei .Kind
es DateTimeKind.Utc
.
Dies unterscheidet sich von Kalenderzeit (auch bekannt als Zivilzeit ), d. h. eine Position im Kalender einer Person, und es gibt viele verschiedene Kalender auf der ganzen Welt. Wir nennen diese Kalender Zeitzonen . Die Kalenderzeit wird durch ein DateTime
wobei .Kind
es DateTimeKind.Unspecified
, oder DateTimeKind.Local
. Und .Local
ist nur in Szenarien sinnvoll, in denen man weiß, wo sich der Computer befindet, der das Ergebnis verwendet. (Zum Beispiel der Arbeitsplatz eines Benutzers)
Warum also DateTimeOffset
anstelle einer UTC DateTime
? Es ist alles eine Frage der Perspektive. Nehmen wir eine Analogie: Wir tun so, als wären wir Fotografen.
Stellen Sie sich vor, Sie stehen auf einer Kalenderzeitleiste und richten eine Kamera auf eine Person, die sich auf der vor Ihnen liegenden Zeitleiste befindet. Sie richten Ihre Kamera nach den Regeln Ihrer Zeitzone aus - die sich aufgrund der Sommerzeit oder anderer Änderungen der gesetzlichen Definition Ihrer Zeitzone regelmäßig ändern. (Sie haben keine ruhige Hand, also ist Ihre Kamera verwackelt.)
Die Person, die auf dem Foto steht, würde den Winkel sehen, aus dem Ihre Kamera kam. Wenn andere Personen Fotos machten, könnten diese aus unterschiedlichen Winkeln stammen. Das ist es, was die Offset
Teil des DateTimeOffset
vertritt.
Wenn Sie also Ihre Kamera mit "Eastern Time" beschriften, zeigen Sie manchmal auf -5 und manchmal auf -4. Überall auf der Welt gibt es Kameras, die alle unterschiedlich beschriftet sind und alle aus verschiedenen Blickwinkeln auf dieselbe Zeitlinie zeigen. Einige von ihnen befinden sich direkt nebeneinander (oder übereinander), so dass es nicht ausreicht, nur den Versatz zu kennen, um festzustellen, auf welche Zeitzone sich die Zeit bezieht.
Und was ist mit UTC? Nun, es ist die einzige Kamera auf dem Markt, die garantiert eine ruhige Hand hat. Sie steht auf einem Stativ, das fest im Boden verankert ist. Sie wird nirgendwo hingehen. Wir nennen ihren Blickwinkel die Nullpunktverschiebung.
Was sagt uns also diese Analogie? Sie liefert einige intuitive Leitlinien.
-
Wenn Sie die Zeit relativ zu einem bestimmten Ort darstellen wollen, stellen Sie sie in Kalenderzeit mit einem DateTime
. Achten Sie nur darauf, dass Sie niemals einen Kalender mit einem anderen verwechseln. Unspecified
sollte Ihre Annahme sein. Local
ist nur nützlich, wenn sie von DateTime.Now
. Ich könnte zum Beispiel Folgendes bekommen DateTime.Now
und speichere sie in einer Datenbank - aber wenn ich sie abrufe, muss ich davon ausgehen, dass sie Unspecified
. Ich kann mich nicht darauf verlassen, dass mein lokaler Kalender derselbe ist, dem er ursprünglich entnommen wurde.
-
Wenn Sie sich immer auf den Zeitpunkt verlassen müssen, sollten Sie sicherstellen, dass Sie die unmittelbare Zeit darstellen. Verwenden Sie DateTimeOffset
um sie durchzusetzen, oder verwenden Sie UTC DateTime
durch Konvention.
-
Wenn Sie einen Moment der augenblicklichen Zeit verfolgen müssen, aber auch wissen wollen, "Welche Zeit hat der Benutzer in seinem lokalen Kalender gesehen?" - dann müssen Sie muss verwenden eine DateTimeOffset
. Dies ist z. B. für Zeiterfassungssysteme sehr wichtig - sowohl aus technischen als auch aus rechtlichen Gründen.
-
Wenn Sie eine bereits aufgezeichnete Datei ändern müssen DateTimeOffset
- Sie haben nicht genügend Informationen im Offset allein, um sicherzustellen, dass der neue Offset für den Benutzer noch relevant ist. Sie müssen auch eine Zeitzonenkennung speichern (denken Sie daran, dass ich den Namen der Kamera brauche, damit ich ein neues Bild aufnehmen kann, auch wenn sich die Position geändert hat).
Es sollte auch darauf hingewiesen werden, dass Noda Zeit hat eine Darstellung namens ZonedDateTime
für diese Aufgabe, während die .Net-Basisklassenbibliothek nichts Vergleichbares bietet. Sie müssten sowohl eine DateTimeOffset
und eine TimeZoneInfo.Id
Wert.
-
Gelegentlich möchten Sie eine Kalenderzeit darstellen, die für denjenigen, der sie betrachtet, lokal ist. Zum Beispiel, wenn Sie definieren, was heute bedeutet. Heute ist immer Mitternacht bis Mitternacht, aber das sind nahezu unendlich viele sich überschneidende Bereiche auf der momentanen Zeitachse. (In der Praxis gibt es eine endliche Anzahl von Zeitzonen, aber man kann die Abstände bis auf den Tick genau ausdrücken.) Stellen Sie also sicher, dass Sie in diesen Situationen wissen, wie Sie entweder die Frage "Wer fragt?" auf eine einzige Zeitzone beschränken oder wie Sie sie gegebenenfalls in die unmittelbare Zeit zurückübersetzen können.
Hier sind noch ein paar andere Kleinigkeiten über DateTimeOffset
die diese Analogie untermauern, und einige Tipps, wie man es richtig macht:
-
Wenn Sie zwei DateTimeOffset
Werte, werden sie vor dem Vergleich zunächst auf einen Offset von Null normiert. Mit anderen Worten, 2012-01-01T00:00:00+00:00
y 2012-01-01T02:00:00+02:00
beziehen sich auf denselben Moment und sind daher gleichwertig.
-
Wenn Sie Unit-Tests durchführen und sicher sein wollen, dass der Offset stimmt, testen Sie beide el DateTimeOffset
Wert, und der .Offset
Eigentum getrennt.
-
In das .Net-Framework ist eine einseitige implizite Konvertierung eingebaut, mit der Sie eine DateTime
in jede DateTimeOffset
Parameter oder Variable. Wenn Sie dies tun, die .Kind
Angelegenheiten . Wenn Sie eine UTC-Art übergeben, wird sie mit einem Null-Offset übertragen, aber wenn Sie entweder .Local
o .Unspecified
wird angenommen, dass es sich um . . Das Framework sagt im Grunde: "Du hast mich gebeten, die Kalenderzeit in die aktuelle Zeit zu konvertieren, aber ich habe keine Ahnung, woher das kommt, also werde ich einfach den lokalen Kalender verwenden. Das ist ein riesiges Problem, wenn Sie eine nicht spezifizierte DateTime
auf einem Computer mit einer anderen Zeitzone. (IMHO - das sollte eine Ausnahme auslösen - tut es aber nicht.)
Unverschämter Versuch:
Viele Menschen haben mir mitgeteilt, dass sie diese Analogie äußerst wertvoll finden, weshalb ich sie in meinen Pluralsight-Kurs aufgenommen habe, Grundlagen zu Datum und Uhrzeit . Eine schrittweise Erklärung der Kameraanalogie finden Sie im zweiten Modul, "Context Matters", im Clip "Calendar Time vs. Instantaneous Time".
0 Stimmen
Wenn es um die Lagerung geht, stackoverflow.com/questions/4715620/ ist ebenfalls interessant.
3 Stimmen
Für Neugierige ist vielleicht auch interessant Die Speicherung von UTC ist kein Patentrezept