DateTime(UTC)の保存とDateTimeOffsetの保存


93

私は通常、データベースの読み取り/書き込みの直前にDateTime変換(UTCから現地時間へ、および現地時間からUTCへ)する「インターセプター」を持っているので、DateTime.Now心配することなくシステム全体で(派生と比較)を使用できます。タイムゾーンについて。

シリアル化とコンピューター間でのデータの移動については、日時が常にUTCであるため、煩わしいことはありません。

日付(SQL 2008-datetime)をUTC形式で保存し続ける必要がありますか、それともDateTimeOffset(SQL 2008-datetimeoffset)を使用して保存する必要がありますか?

データベース(datetime型)のUTC日付は長い間機能していて知られていますが、なぜそれを変更するのですか?利点は何ですか?

私はすでにこのような記事を調べましたが、100%確信しているわけではありません。何かご意見は?



1
参照:DateTime vs DateTimeOffset-.Net用に記述されていますが、概念的にはSQLにも適用されます。
Matt Johnson-Pint 2014

回答:


131

UTCを単独で使用できないという大きな違いが1つあります。

  • このようなシナリオがある場合

    • 1つのサーバー複数のクライアント(すべて地理的に異なるタイムゾーン
    • クライアントは日時情報を含むいくつかのデータを作成します
    • クライアントはすべてを中央サーバーに保存します
  • 次に:

    • datetimeoffsetには、クライアントのローカル時刻と UTC時刻へのオフセットも格納さます。
    • すべてのクライアントは、すべてのデータのUTC時刻と、情報が発信された場所の現地時間を知っています。
  • だが:

    • UTC日時はUTC日時のみを格納するため、データが発生したクライアントの場所の現地時間に関する情報はありません。
    • 他のクライアントは、日時情報が取得された場所の現地時間を知らない
    • 他のクライアントは、データベースのローカル時間(UTC時間を使用)からのみ計算できます。データが発生したクライアントのローカル時間は計算できません。

簡単な例は、航空券予約システムです...航空券には2つの時間が含まれている必要があります。


2
これは私がそれがいつ適切であるかについて読んだ最も良い説明であり、私はたくさん読んだ私たちにとって、これからはそうではないようです。外部データの時間をUTCで取得し、必要に応じて別のソースから場所を特定します(これまでにない)。それをとても明白に見せてくれてありがとう。
アンドリューバッカー2012

19
「datetimeoffsetはUTC時間とクライアントのローカル時間へのオフセットも格納する」と述べましたが、datetimeoffsetはローカル時間+オフセット、またはUTC時間+オフセット+0を格納します。
Serhii Kyslyi 2013年

DTベースはUTCであるため、DTOをDTにキャストすることもできます(ただし、これはデータベースを使用するすべての人にとって追加の手順であり、おそらくUTC時間だけを使用するよりも簡単ではありません)
iliketocode

2
DateTmeOffsetは、「UTC時間とUTCオフセット」ではなく、「現地時間とUTCオフセット」を格納するように見えます。datetimeにキャストするか、datepart関数のいずれかを使用すると、ローカルの日付と時刻のコンポーネントが取得されます。
Triynko

すべてのクライアントは、すべてのデータのUTC時刻と、情報が発信された場所の現地時間を知っています」日付フィールドの一部として格納することは、その場合、正規化されていないように感じます。ユースケースは何ですか-つまり、UTCを使用してオフセットをプルアウトしないのはなぜですかInputLocationId(または同様の正規化されたエンティティ)。計算が必要になります(こんにちは、例外 ...特にあなた、インディアナ州)が、それでも決定論的なプロセスです-そして、アプリの日時ロジックのバランスは簡単です。
ruffin

23

あなたはすべての歴史的な時間にUTCを使用することが絶対に正しいです(つまり、記録イベントが発生しました)。UTCから現地時間に移動することは常に可能ですが、常に逆になることはありません。

いつ現地時間を使うのですか?この質問に答えてください:

政府が突然夏時間を変更することを決定した場合、このデータをそれに合わせて変更しますか?

答えが「はい」の場合のみ、現地時間を保存します。明らかにそれは将来の日付のみであり、通常は何らかの形で人々に影響を与える日付のみです。

なぜタイムゾーン/オフセットを保存するのですか?

まず、アクションを実行したユーザーのオフセットを記録したい場合は、おそらくそれを行うのが最善です。つまり、ログイン時にそのユーザーの場所とタイムゾーンを記録します。

次に、表示用に変換する場合、そのタイムゾーンのすべてのローカルタイムオフセット遷移のテーブルが必要です。現在のオフセットだけでは十分ではありません。6か月前の日付/時刻を表示している場合、オフセットは異なる。


4
Windows UTCから現地時間への変換では、過去の日付の夏時間が変更されるときに考慮されます。その場合、なぜ現地時間を保存する必要があるのか​​わかりません。
Jamiegs、2011年

1
@Jamiegs Windowsは、「。NET DateTimeのドキュメントで示唆されているように」「最後の履歴情報」のみを歴史的に認識しています。包括的ではありません。

2
もちろん、イベントの場所も保存する必要があります。そうしないと、イベントが発生した「現地時間」はわかりません。
keuleJ 2017

20

DATETIMEOFFSETを使用すると、1つのフィールドに現地時間とUTC時間を格納できます。

これにより、データを処理して表示する必要がなく、現地時間またはUTC時間での非常にシンプルで効率的なレポートが可能になります。

これらは、最も一般的な2つの要件です。ローカルレポートのローカル時間とグループレポートのUTC時間です。

現地時間はDATETIMEOFFSETのDATETIME部分に格納され、UTCからのOFFSETはOFFSET部分に格納されます。したがって、変換は簡単であり、データの取得元のタイムゾーンを知る必要がないため、すべてデータベースレベルで実行できます。 。

ミリ秒までの時間を必要としない場合(たとえば、分または秒まで)、DATETIMEOFFSET(0)を使用できます。DATETIMEOFFSETフィールドは、8バイトのストレージのみを必要とします-DATETIMEと同じです。

したがって、UTC DATETIMEではなくDATETIMEOFFSETを使用すると、レポートの柔軟性、効率、および単純さが向上します。


エンティティフレームワークが悪すぎると、datetimeoffsetフィールドのローカルの日時にアクセスできなくなり、特定のローカルの日付を照会できなくなります。
Triynko

@Triynkoはあなたが何を意味するのか説明できますか?例?
reidLinden 2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.