DateTimeOffset
は、瞬間時間(絶対時間とも呼ばれます)を表します。つまり、すべての人にとって普遍的な瞬間を意味します(うるう秒、または時間拡張の相対論的効果は考慮されません)。瞬間的な時間を表すもう1つの方法は、DateTime
whereを使用すること.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
-新しいオフセットがまだユーザーに関連していることを確認するのに十分な情報だけがオフセットにありません。タイムゾーン識別子も保存する必要があります(位置が変わっても新しい写真を撮れるように、カメラの名前が必要だと思います)。
またことを指摘すべきである野田時間が呼ばれる表現があるZonedDateTime
の.Netベースクラスライブラリは、同様の何かを持っていませんが、このために。DateTimeOffset
とTimeZoneInfo.Id
値の両方を保存する必要があります。
時々、「誰が見ているか」に対してローカルなカレンダー時間を表すことが必要になる場合があります。たとえば、今日の意味を定義するとき。今日は常に午前0時から午前0時までですが、これらは瞬間的なタイムライン上のほぼ無限の数の重複範囲を表しています。(実際にはタイムゾーンの数は有限ですが、目盛りまでのオフセットを表すことができます)したがって、これらの状況では、「誰が尋ねているのか」を制限する方法を必ず理解してください。単一のタイムゾーンまで質問するか、必要に応じてそれらを瞬時の時間に変換し直すことに対処します。
DateTimeOffset
この類似性を裏付けるためのその他のいくつかの小さな点と、それをまっすぐに保つためのいくつかのヒントを次に示します。
2つのDateTimeOffset
値を比較する場合、比較する前に、まずゼロオフセットに正規化されます。つまり、同じ瞬間の瞬間2012-01-01T00:00:00+00:00
を2012-01-01T02:00:00+02:00
指し、したがって同等です。
ユニットテストを実行していて、オフセットを確認する必要がある場合は、値とプロパティの両方を個別にテストDateTimeOffset
し.Offset
ます。
.Netフレームワークには、一方向の暗黙的な変換が組み込まれており、DateTime
任意のDateTimeOffset
パラメーターまたは変数にを渡すことができます。その際、重要。UTCの種類を渡すと、オフセットがゼロで実行されますが、またはのいずれかを渡すと、ローカルであると見なされます。フレームワークは基本的に「まあ、あなたは私にカレンダー時間を瞬時時間に変換するように頼んだが、これがどこから来たのかわからないので、私はローカルカレンダーを使用するつもりだ」と言っています。これは、タイムゾーンが異なるコンピュータに指定されていないものをロードする場合、大きな問題になります。(私見-それは例外をスローするはずです-それはしません。).Kind
.Local
.Unspecified
DateTime
恥知らずなプラグ:
このアナロジーは非常に価値があると多くの人が私に話してくれたので、私はそれをPluralsightコースのDate and Time Fundamentalsに含めました。2番目のモジュール「Context Matters」のカメラアナロジーの段階的なウォークスルーは、「カレンダー時間と瞬間時間」というタイトルのクリップにあります。