一般に、時間をUTCで保存し、 here および here で説明したように、ベストプラクティスです。
そのタイムゾーンで夏時間のオン/オフに関係なく、常に同じ現地時間である終了時刻など、繰り返し発生するイベントがあるとします。また、特定のタイムゾーンでDSTがオンまたはオフになったときに、時間を手動で変更しないという要件もあります。また、終了時刻がAPI(つまりGetEndTimeByEvent)を介して他のシステムから要求されるたびに、常にUTC形式で終了時刻を送信することも要件です。
アプローチ1:決定された場合TCで保存するデータベーステーブルに以下のように保存できます。
Event UTCEndTime
=====================
ABC 07:00:00
MNO 06:00:00
PQR 04:00:00
最初のイベントABCの場合、UTCの終了時刻は午前7時で、UTCから2012年7月1日の現地時間に表示するように変換すると、現地時間17:00になり、2012年10月10日に変換すると(そのタイムゾーンでDSTがオンになっている日付)は、午後6時になりますが、これは正しい終了時間ではありません。
考えられる1つの方法は、追加の列にDST時間を格納し、タイムゾーンがDST ONになっているときにその時間を使用することです。
アプローチ2:ただし、ローカル時間として保存の場合、たとえばイベントABCの場合、fromへの変換がないため、どの日付でも常に17:00になります。 UTCから現地時間。
Event LocalEndTime
=======================
ABC 17:00:00
MNO 16:00:00
PQR 14:00:00
また、アプリケーションレイヤーはローカル時間をUTC時間に変換して、(API GetEndTimeByEvent)を介して他のシステムに送信します。
この場合、UTCで時刻を保存することをお勧めしますか?はいの場合、ローカル時間を一定にする方法は?
関連質問: TC以外の時間を保存する正当な理由はありますか?
その質問に答えるには、UTCを使用してタイムスタンプを保存することの利点について考える必要があると思います。
個人的には、その主な利点は、時間は常に(ほとんど)consistentに保証されることだと思います。つまり、タイムゾーンが変更されるか、DSTが適用されるたびに、時間内に前後に移動することはありません。これは、ファイルシステム、ログなどで特に役立ちます。しかし、あなたのアプリケーションでは必須ですか?
2つのことを考えてください。まず、DSTクロックシフトの時間について。イベントは午前2時から午前3時の間に発生する可能性がありますか(クロックシフトが行われた日)?それではどうなりますか?
第二に、アプリケーションは実際のタイムゾーンの変更の影響を受けますか?言い換えれば、ロンドンからワルシャワまで飛行機で行き、コンピューターのタイムゾーンを適切に変更しますか?その場合はどうなりますか?
これらの質問の両方にnoと答えた場合、現地時間の方が良いでしょう。アプリケーションがよりシンプルになります。しかし、あなたがyesに少なくとも一度答えたなら、もっと考えるべきだと思う。
そして、それはすべてデータベースに関するものでした。もう1つは、アプリケーションで内部的に使用される時間形式です。これは、実際にその時間で何をするかによって異なります。
APIを介して時間を公開することについて言及しました。アプリケーションは、すべての要求でデータベースを照会しますか?時間を内部的にUTCとして保存する場合は、それを行うか、DST /タイムゾーンの変更時にキャッシュ時間を調整/プルーニングする必要があります。
時間そのもので何かをしますか?印刷のようにイベントは8時間以内に発生しますまたはその時間の間に自身を中断しますか? 「はい」の場合、UTCの方がおそらく優れています。もちろん、前述のすべての問題について考える必要があります。
私はこのように考えるのが好きです:
コンピューターは、時間を人間が理解できる表現として気にしません。彼らは、タイムゾーン、日付と時刻の文字列のフォーマット、またはそのいずれも気にしません。時間の解釈と表現の方法に関心があるのは人間だけです。
データベースの長所:時間を数値として保存する-UNIXエポック(1970-01-01から経過した秒数)またはUTCタイムスタンプ(タイムゾーンまたは夏時間情報なし)のいずれか。必要な場合にのみ、人間が理解できる方法で時間を表現することにのみ関わってください。つまり、アプリケーションロジック、レポートシステム、コンソールアプリケーション、または人間がデータを表示するその他の場所で使用します。
以下は、真のマルチテナントグローバルSaaS製品には適用されないため、この意見は単純な「基幹業務」アプリ開発者を対象としています。
UTCとして保存することは問題ありませんが、これを行うと痛みを引き起こす要件が1つあります。「1日に発生するXの数を示すレポートを作成してもらえますか?」
日付をUTCとして保存すると、この要件により苦痛が生じます。アプリケーションサーバーとレポートにタイムゾーン調整コードを記述する必要があります。日付の条件を含むデータに対して実行するすべてのアドホッククエリでは、これを考慮する必要があります。
アプリケーションが次の条件を満たす場合:
サーバーのタイムゾーン設定の問題から分離するライブラリを使用しながら、日付時刻をローカル日付時刻として保存することをお勧めします(例:.netの世界ではNoda.Time)。
システム間メッセージがISO 8601を使用し、データベースがOriginローカル時間+オフセット(MSSQLのdatetimeoffset
またはISO 8601がキャプチャするMongoのISODate
など)を保存している場合、 .NETのDateTimeOffset
またはJavaまたはコードで同等のJava $ ===)のOffsetDateTime
のみを使用すると、変換はまったく必要ありません。保存するだけです。すべての比較関数が機能します。
永続性でUTCに変換すると、ユーザーの視点からのオフセットが失われます。 10年前にユーザーがドキュメントに署名したときに表示するのは、今では難しい問題です。 UTCからそれを計算するということは、その地域でその時点で使用されていたDSTルールを検索することを意味します。悪夢。
永続性のためにUTCに変換することに慣れている理由は、正しいことを行うために正しいデータ構造/データ型を使用したことがないためだと思います。
時間コンポーネントは、ゾーンなしでのみ保存します。 APIがサービスを提供する必要がある場合は常に、正しい日付を追加し、その日付の現地時間としてUTCに変換します。
データベース= 17:00(日付なしのタイムスタンプ、バイトとしての時間、バイトとしての分、文字列を使用)
取得=イベントが必要な日付+データベース17:00 =>これをローカルからUTCに変換
このようにして、常に正しい時間をUTCで提供します。
ほとんどの時間APIが想定しているように、実際には特定の時点を保存していません。データベースがサポートしている場合は間隔を使用するか(PostgreSQLがサポートします)、深夜または対応するスケジュールの開始(月曜日、月初など)からの秒数(分/時間)を表す整数として保存します。どちらの場合でも、システム間で「時間」がどのように処理されるかを心配する多くの頭痛をなくし、ビューで秒を時刻に変換するという非常に小さな頭痛だけを追加しました。