DateTime vs DateTimeOffset
Derzeit haben wir eine standard-Art des Umgangs mit .Netto-DateTimes in einer Zeitzone bewusst Weg: Wann immer wir produzieren eine DateTime
wir tun es im UTC-Format (z.B. mit DateTime.UtcNow
), und immer, wenn wir eins, sind wir wieder zurück konvertieren von UTC und der Ortszeit des Anwenders.
Das funktioniert, aber ich ' ve wurde Lesen über DateTimeOffset
und wie es erfasst die lokale und UTC Zeit im Objekt selbst. Die Frage ist also, was wären die Vorteile der Verwendung von DateTimeOffset
vs, was wir bereits tun?
InformationsquelleAutor der Frage David Reis | 2010-12-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
DateTimeOffset
ist eine Darstellung von momentane Zeit (auch bekannt als absolute Zeit). Damit meine ich einen moment in der Zeit, ist universal für alle (nicht Buchhaltung für Schaltsekundenoder die relativistischen Effekte der Zeitdilatation). Eine weitere Möglichkeit zur Darstellung momentane Zeit wird mit einemDateTime
wo.Kind
istDateTimeKind.Utc
.Dies ist ein Unterschied zu Kalender Zeit (auch bekannt als bürgerlichen Zeit), die position, die jemand auf den Kalender, und es gibt viele verschiedene Kalender, über den ganzen Globus. Wir nennen diese Kalender Zeitzonen. Kalender Zeit ist vertreten durch eine
DateTime
wo.Kind
istDateTimeKind.Unspecified
oderDateTimeKind.Local
. Und.Local
ist nur sinnvoll in Szenarien, in denen Sie eine implizite Verständnis, wenn der computer, mit dem Ergebnis positioniert ist. (Beispielsweise die Arbeitsstation eines Benutzers)Also, warum
DateTimeOffset
statt UTCDateTime
? Es ist alles über Perspektive. Verwenden wir eine Analogie - wir werden so tun, als sein Fotografen.Stellen Sie sich vor Sie stehen auf einem Kalender Zeitleiste, die eine Kamera auf eine person, auf die momentane timeline legte vor Ihnen. Sie line-up Ihre Kamera nach den Regeln Ihrer Zeitzone, die periodisch durch die Sommerzeit, oder durch andere änderungen der rechtlichen definition Ihrer Zeitzone. (Sie nicht über eine ruhige hand, so dass Ihre Kamera ist wackelig.)
Die person auf dem Foto zu sehen wäre der Winkel, in dem Sie Ihre Kamera kam. Wenn andere fotografieren, Sie könnten aus verschiedenen Blickwinkeln. Dies ist, was die
Offset
Teil derDateTimeOffset
darstellt.Also, wenn Sie ein label für deine Kamera "Eastern Time", manchmal sind Sie runter von -5, und manchmal weist du von -4. Es sind Kameras auf der ganzen Welt, die alle mit unterschiedlichen Dingen, und alle zeigen auf den gleichen Momentanwert-timeline aus verschiedenen Blickwinkeln. Einige von Ihnen sind direkt neben (oder über) einander, so dass nur die Kenntnis der offset ist nicht genug, um festzustellen, welche Zeitzone die Zeit bezogen ist.
Und was ist UTC? Nun, es ist eine Kamera gibt, wird garantiert eine ruhige hand. Es ist auf einem Stativ fest verankert in den Boden. Es ist nicht überall. Nennen wir den Winkel der Perspektive der null-offset.
Also - was hat diese Analogie uns sagen? Es bietet eine Reihe von intuitiven Richtlinien.
Wenn Sie, die Zeit relativ zu einem Ort, der insbesondere vertritt Sie im Kalender mit einem
DateTime
. Nur sicher sein, Sie don ' T ever verwirren Sie einen Kalender mit einem anderen.Unspecified
sollte Ihre Annahme.Local
ist nur sinnvoll, ausDateTime.Now
. Ich könnte zum Beispiel erhaltenDateTime.Now
und speichern Sie es in eine Datenbank, aber wenn ich Sie abrufen, ich muss davon ausgehen, dass esUnspecified
. Ich kann mich nicht darauf verlassen, dass meine lokalen Kalender ist der gleiche Kalender, der es ursprünglich entnommen.Wenn Sie müssen immer sicher sein, der moment, stellen Sie sicher, dass Sie, die momentane Zeit. Verwenden
DateTimeOffset
zu erzwingen, oder UTC verwendenDateTime
durch Konvention.Wenn Sie brauchen, um zu verfolgen, einen moment der momentanen Zeit, aber Sie wollen auch wissen, "Was Zeit hat der user glaube, es war auf Ihren lokalen Kalender?" - dann sind Sie muss Verwendung eines
DateTimeOffset
. Dies ist sehr wichtig für die Zeitnahme-Systeme, zum Beispiel - sowohl aus technischen als auch rechtlichen Bedenken.Wenn Sie jemals brauchen, um zu ändern, eine früher aufgezeichnete
DateTimeOffset
- Sie haben nicht genug Informationen in der offset-allein, um sicherzustellen, dass der neue offset ist immer noch relevant für den Benutzer. Sie müssen auch speichern timezone identifier (think - ich brauche den Namen der Kamera, so kann ich ein neues Bild aufnehmen, selbst wenn die position geändert hat).Es sollte auch darauf hingewiesen werden, dass Noda Zeit hat eine Vertretung genannt
ZonedDateTime
für diese, während die .Net base class library nicht haben, etwas ähnliches. Würden Sie benötigen zum speichern einerDateTimeOffset
und einTimeZoneInfo.Id
Wert.Gelegentlich werden Sie wollen, stellen Sie eine Kalender-Zeit, die lokale "wem ist es bei der Suche". Zum Beispiel, wenn die Definition, was heute bedeutet. Heute wird immer von Mitternacht bis Mitternacht, aber diese stellen eine nahezu unendliche Anzahl von sich überlappenden Bereiche auf der momentanen timeline. (Wir haben In der Praxis eine endliche Anzahl von Zeitzonen, aber Sie können express-offsets nach unten, um die Zecke), So dass in diesen Situationen, stellen Sie sicher, dass Sie verstehen, wie Sie entweder begrenzen "wer fragt?" - Frage zu einer einzigen Zeit-zone, oder befassen sich mit der übersetzung, Sie wieder zu momentaner Zeit als angemessen.
Hier sind ein paar andere kleine Sachen über
DateTimeOffset
sichern diese Analogie, und einige Tipps für die Aufbewahrung es gerade:Wenn Sie vergleichen zwei
DateTimeOffset
Werte, werden Sie zunächst normalisiert, um den null-offset vor dem Vergleich. In anderen Worten,2012-01-01T00:00:00+00:00
und2012-01-01T02:00:00+02:00
beziehen sich auf die gleiche momentane moment, und sind daher äquivalent.Wenn Sie tun, jede unit testing und sicher sein müssen für den offset -, test - beide die
DateTimeOffset
Wert, und die.Offset
Eigentum getrennt.Es ist ein one-way implizite Konvertierung in das .Net framework, mit der Sie an einem
DateTime
in jedemDateTimeOffset
parameter oder eine variable. Wenn Sie dies tun, die.Kind
Angelegenheiten. Wenn Sie ein UTC-Art, es wird mit einem null-offset, aber wenn Sie passieren entweder.Local
oder.Unspecified
es wird vermutet, dass lokalen. Der Rahmen ist im Grunde sagen, "Nun, Sie fragte mich, zu konvertieren, Kalender, Zeit, momentane Zeit, aber ich habe keine Ahnung, wo das kam aus, also ich werde einfach zu verwenden lokalen Kalender." Dies ist ein großes Manko, wenn Sie laden, bis eine unbestimmteDateTime
auf einem computer mit einer anderen Zeitzone. (IMHO - das sollte eine Ausnahme ausgelöst werden - muss es aber nicht.)Shameless Plug:
Viele Menschen mit mir geteilt haben, dass Sie finden diese Analogie äußerst wertvoll, so habe ich es in meinen Pluralsight-Kurs, Datum und Zeit Grundlagen. Finden Sie eine Schritt-für-Schritt-Komplettlösung von der Kamera Analogie in dem zweiten Modul "Context Matters", in dem clip mit dem Titel "Kalender-Zeit vs. Momentane Zeit".
InformationsquelleAutor der Antwort Matt Johnson
Von Microsoft:
Quelle: "Die Wahl Zwischen" DateTime DateTimeOffset, Zeit, und TimeZoneInfo"MSDN
Verwenden wir
DateTimeOffset
für fast alles als unser Antrag befasst sich mit bestimmten Punkten in der Zeit (z.B. wenn ein Datensatz wurde erstellt/aktualisiert). Als seitliche Anmerkung, wir benutzenDATETIMEOFFSET
in SQL Server 2008 sowie.Sehe ich
DateTime
als nützlich, wenn Sie wollen Angebot mit Termin nur, mal nur, oder befassen sich mit entweder in einem Allgemeinen Sinn. Zum Beispiel, wenn Sie einen alarm haben, dass Sie gehen wollen, die sich jeden Tag um 7 Uhr auf, Sie könnte Shop, die in einerDateTime
Verwendung einesDateTimeKind
vonUnspecified
weil Sie es wollen zu gehen um 7 Uhr morgens, unabhängig von der Sommerzeit. Aber wenn Sie möchten, stellen die Geschichte von alarm-Ereignissen, die Sie verwenden würdenDateTimeOffset
.Vorsicht, wenn Sie mit einer Mischung aus
DateTimeOffset
undDateTime
vor allem bei der Zuweisung und der Vergleich zwischen den Typen. Auch, vergleichen Sie nurDateTime
Instanzen, die die gleichenDateTimeKind
weilDateTime
ignoriert timezone offset beim Vergleich.InformationsquelleAutor der Antwort Clay
DateTime ist in der Lage die Speicherung nur zwei verschiedene Zeiten, die lokale Zeit und UTC. Die Art Eigenschaft gibt an, welche.
DateTimeOffset erweitert diese durch speichern zu können, die lokale Uhrzeit von überall in der Welt. Es speichert auch die offset zwischen der lokalen Zeit und der UTC. Beachten Sie, wie DateTime kann dies nicht tun, es sei denn, Sie würden ein zusätzliches Mitglied Ihrer Klasse zu speichern, die UTC-offset. Oder immer nur die Arbeit mit UTC. Das ist an sich eine feine Idee btw.
InformationsquelleAutor der Antwort Hans Passant
Es gibt ein paar Orte, wo
DateTimeOffset
Sinn macht. Man ist, wenn man den Umgang mit immer wiederkehrenden Veranstaltungen und Sommerzeit. Lassen Sie uns sagen ich will ein alarm losgehen, um 9 Uhr jeden Tag. Wenn ich den "speichern als UTC, Anzeige als local time" - Regel, dann wird der alarm geht Los in verschiedenen Zeit, wenn die Sommerzeit in Kraft ist.Gibt es wahrscheinlich noch andere, aber die oben genannten Beispiel ist eigentlich eine, ich habe in der Vergangenheit (das war, bevor die Zugabe von
DateTimeOffset
der BCL - meine Lösung war zu der Zeit explizit speichern der Zeit in die lokale Zeitzone, und speichern Sie die Zeitzone-Informationen entlang Seite es: im Grunde, wasDateTimeOffset
hat intern).InformationsquelleAutor der Antwort Dean Harding
Der wichtigste Unterschied ist, dass DateTime speichert keine Zeitzone Informationen und DateTimeOffset nicht.
Obwohl DateTime unterscheidet zwischen UTC-Zeit und Lokaler, gibt es absolut keine explizite Zeitzonen-offset zugeordnet. Wenn Sie haben irgendeine Art von Serialisierung oder Konvertierung der Zeitzone des Servers verwendet werden. Selbst wenn Sie manuell erzeugen einer lokalen Zeit, indem Sie Minuten offset der UTC-Zeit, können Sie immer noch etwas in der Serialisierung Schritt, weil (aufgrund fehlen jeglicher expliziten offset in DateTime) wird es mit der Zeitzone des Servers kompensiert.
Zum Beispiel, wenn Sie serialisieren eines DateTime-Wert mit Art=Lokale Verwendung Json.Net und eine ISO-konforme Datum-format, erhalten Sie einen string wie
2015-08-05T07:00:00-04
. Beachten Sie, dass im letzten Teil (-04) hatte nichts zu tun mit dem DateTime-oder eine Aufrechnung, die Sie verwendet, um zu berechnen, es... es ist nur rein die server-Zeitzone offset.Mittlerweile, DateTimeOffset schließt ausdrücklich die Aufrechnung. Es dürfen nicht die Namen von den Zeit-zone, aber wenigstens enthält es die Verschiebung, und wenn Sie es zu serialisieren, Sie gehen zu bekommen, der explizit offset in Ihrem Wert, anstatt von dem, was der server lokale Zeit passiert zu sein.
InformationsquelleAutor der Antwort Triynko
Meisten Antworten sind gut , aber ich dachte an das hinzufügen einige weitere links des MSDN für mehr Informationen
TimeZoneInfo Arten, von denen alle verwendet werden können, um Anwendungen zu erstellen
das arbeiten mit Datumsangaben und Uhrzeiten.
InformationsquelleAutor der Antwort dekdev
Ein wichtiger Unterschied ist, dass
DateTimeOffset
verwendet werden können in Verbindung mitTimeZoneInfo
zu konvertieren, um die lokale Uhrzeit in anderen Zeitzonen als der aktuelle.Dies ist nützlich, wenn ein server-Anwendung (z.B. ASP.NET), die den Zugriff durch Benutzer in verschiedenen Zeitzonen.
InformationsquelleAutor der Antwort Joe
Nur die negative Seite des DateTimeOffset ich sehe, ist, dass Microsoft "vergessen" (durch design) unterstützen Sie in Ihrer XmlSerializer-Klasse. Kein problem mit dem DataContractSerializer (und vielleicht andere, aber brauchen, um zu überprüfen, dass). Auf jeden Fall gibt es einen workaround, ich erklärte in den offiziellen MS-connect-Problem hier:
https://connect.microsoft.com/VisualStudio/feedback/details/288349/datetimeoffset-is-not-serialized-by-a-xmlserializer
Wie Sie sehen können, wird Microsoft kein Update, obwohl es ist ein eingebauter Typ und Sie empfehlen, wir verwenden es standardmäßig; crazy, aber wahr! Ich noch sagen, gehen Sie vor und verwenden Sie DateTimeOffset und TimeZoneInfo, weil Sie alle Vorteile, nur Vorsicht beim erstellen von Personen, die möglicherweise werden in XML serialisiert (alle business-Objekte).
InformationsquelleAutor der Antwort Tony Wall