DateTimeOffset
瞬間時間(絶対時間とも呼ばれます)の表現です。つまり、すべての人にとって普遍的な瞬間を意味します(うるう秒、または時間の遅れの相対論的効果を考慮していません)。瞬間時間を表す別の方法は、whereisを使用するDateTime
こと.Kind
ですDateTimeKind.Utc
。
これは、誰かのカレンダー上の位置であるカレンダー時間(常用時とも呼ばれます)とは異なり、世界中にさまざまなカレンダーがあります。これらのカレンダーをタイムゾーンと呼びます。カレンダーの時間は、、またはDateTime
で表されます。そして、結果を使用しているコンピューターがどこに配置されているかを暗黙的に理解しているシナリオでのみ意味があります。(たとえば、ユーザーのワークステーション).Kind
DateTimeKind.Unspecified
DateTimeKind.Local
.Local
では、なぜDateTimeOffset
UTCの代わりにDateTime
? それはすべて視点についてです。 例えを使ってみましょう-私たちは写真家のふりをします。
あなたがカレンダーのタイムラインに立って、目の前に配置された瞬間的なタイムライン上の人物にカメラを向けていると想像してください。タイムゾーンのルールに従ってカメラを並べます。これは、夏時間のため、またはタイムゾーンの法的な定義に対するその他の変更のために定期的に変更されます。(手が安定していないため、カメラが不安定です。)
写真に立っている人は、あなたのカメラがどこから来たのかを見るでしょう。他の人が写真を撮っている場合、彼らは異なる角度からである可能性があります。これは、のOffset
一部がDateTimeOffset
表すものです。
したがって、カメラに「東部標準時」というラベルを付けると、-5から指している場合もあれば、-4から指している場合もあります。世界中にカメラがあり、すべて異なるものにラベルが付けられており、すべてが異なる角度から同じ瞬間のタイムラインを指しています。それらのいくつかは互いに隣接している(または上にある)ため、オフセットを知っているだけでは、時間がどのタイムゾーンに関連しているかを判断するのに十分ではありません。
そしてUTCはどうですか?まあ、それは安定した手を持っていることが保証されているそこにある唯一のカメラです。三脚の上にあり、地面にしっかりと固定されています。それはどこにも行きません。その遠近法をゼロオフセットと呼びます。

それで、このアナロジーは私たちに何を伝えますか?それはいくつかの直感的なガイドラインを提供します-
特にある場所に関連する時間を表す場合は、カレンダー時間で。を使用して表しDateTime
ます。あるカレンダーを別のカレンダーと混同しないように注意してください。 Unspecified
あなたの仮定でなければなりません。 Local
から来るだけで便利ですDateTime.Now
。たとえば、取得DateTime.Now
してデータベースに保存する場合がありますが、取得するときは、であると想定する必要がありUnspecified
ます。私のローカルカレンダーが元々取得されたものと同じであるとは信じられません。
常に瞬間を確認する必要がある場合は、瞬間的な時間を表していることを確認してください。DateTimeOffset
それを強制するために使用するかDateTime
、慣例によりUTCを使用します。
瞬間的な時間を追跡する必要があるが、「ユーザーはそれがローカルカレンダー上で何時だと思ったのか」も知りたい場合。-次に、を使用する必要DateTimeOffset
があります。これは、たとえば、技術的および法的な懸念の両方において、計時システムにとって非常に重要です。
以前に記録されたものを変更する必要がある場合DateTimeOffset
は、オフセットだけでは、新しいオフセットがユーザーに関連していることを確認するのに十分な情報がありません。タイムゾーン識別子も保存する必要があります(たとえば、位置が変わっても新しい写真を撮れるように、そのカメラの名前が必要です)。
また、 Noda Timeにはこれを必要とする表現がありZonedDateTime
ますが、.Net基本クラスライブラリには同様のものがないことも指摘しておく必要があります。DateTimeOffset
aと値の両方を保存する必要がありTimeZoneInfo.Id
ます。
場合によっては、「それを見ている人」にローカルなカレンダー時間を表現したい場合があります。たとえば、今日の意味を定義するとき。今日は常に真夜中から真夜中ですが、これらは瞬間的なタイムライン上でほぼ無限の数の重複する範囲を表しています。(実際には、タイムゾーンの数には限りがありますが、目盛りまでのオフセットを表現できます)したがって、このような状況では、「誰が質問しているのか」を制限する方法を理解してください。単一のタイムゾーンに質問するか、必要に応じてそれらを瞬間的な時間に戻すことに対処します。
これは、このアナロジーを裏付ける他のいくつかのちょっとしたDateTimeOffset
ことと、それをまっすぐに保つためのいくつかのヒントです。
2つの値を比較する場合、比較DateTimeOffset
する前に、最初にゼロオフセットに正規化されます。言い換えれば、2012-01-01T00:00:00+00:00
と2012-01-01T02:00:00+02:00
は同じ瞬間の瞬間を指し、したがって同等です。
単体テストを実行していて、オフセットを確認する必要がある場合は、値とプロパティの両方を個別にテストしてください。DateTimeOffset
.Offset
DateTime
.Net Frameworkには、任意のDateTimeOffset
パラメーターまたは変数にを渡すことができる一方向の暗黙的な変換が組み込まれています。そうするとき、.Kind
問題。UTCの種類を渡すと、オフセットはゼロになりますが、またはのいずれかを渡す.Local
と、ローカル.Unspecified
であると見なされます。フレームワークは基本的に、「カレンダーの時刻を瞬間的な時刻に変換するように言われましたが、これがどこから来たのかわからないので、ローカルカレンダーを使用します」と言っています。異なるタイムゾーンのコンピュータに不特定のものをロードする場合、これは大きな落とし穴です。(IMHO-例外をスローする必要があります-しかし、そうではありません。)DateTime
恥知らずなプラグ:
多くの人がこのアナロジーは非常に価値があると私と共有しているので、私はそれを私のPluralsightコースのDate andTimeFundamentalsに含めました。2番目のモジュール「ContextMatters」の「CalendarTimevs.Instantaneous Time」というタイトルのクリップで、カメラのアナロジーのステップバイステップのウォークスルーを見つけることができます。