すべてを GMT で保存しますか?
埋め込まれたオフセットを使用して入力された方法ですべてを保存しますか?
レンダリングするたびに計算しますか?
「1分前」の相対時刻を表示しますか?
すべてを GMT で保存しますか?
埋め込まれたオフセットを使用して入力された方法ですべてを保存しますか?
レンダリングするたびに計算しますか?
「1分前」の相対時刻を表示しますか?
UTC で保存する必要があります。そうしないと、夏時間などの期間中の履歴レポートや動作が...おかしくなります。GMT は現地時間であり、UTC に対する夏時間の影響を受けます (そうではありません)。
現地時間を保存している場合、異なるタイムゾーンにいるユーザーへのプレゼンテーションは本当にひどいものになる可能性があります。生データが UTC の場合、簡単にローカルに調整できます。ユーザーのオフセットを追加するだけで完了です!
Joel はポッドキャストの 1 つでこれについて (回りくどい方法で) 話しました - 彼はデータを可能な限り最高の解像度で保存するように言いました(「忠実度」を検索してください)。そのため、UTC として保存すると言います。現地時間は、そのタイムゾーンにいない人に合わせて調整する必要があり、それは大変な作業です。また、たとえば、時刻を保存したときに夏時間が有効であったかどうかを保存する必要があります。ユク。
過去のデータベースでは、ソート用の UTC と表示用の現地時間の 2 つを格納していました。そうすれば、ユーザーもコンピューターも混乱しません。
さて、表示に関して: 確かに、「3 分前」のことを行うことができますが、UTC を保存する場合に限ります。そうしないと、異なるタイムゾーンで入力されたデータは「-4 時間前」として表示されるなどのことを行います。人々を驚かせます。実際の時間を表示する場合、人々はそれを現地時間で表示することを好みます。また、データが複数のタイムゾーンで入力されている場合、UTC を保存している場合にのみ簡単に表示できます。
答えは、いつものように「依存」です。
それは、あなたが時間とともに何を説明しているか、およびデータがどのように提供されたかによって異なります。時間の値を保存する方法を決定する鍵は、タイムゾーンを削除することで情報が失われるかどうかを判断することと、ユーザーを驚かせないことです。
データを UTC time_t に保存することには明確な利点があります。これは単一の int であるため、すばやく並べ替えて簡単に保存できます。
問題は特定の領域に分割されているように見えます。
それぞれに次のサブクラスがあります。
それらを 1 つずつ見ていきましょう。
システム提供: システムを UTC で実行することをお勧めします。そうすれば、タイムゾーンの問題を回避でき、情報が失われることもありません (常に UTC です)。
履歴データ: これらは、システム ログ ファイル、プロセス統計、トレース、コメントの日付/時刻などです。データは変更されず、タイムゾーン記述子はさかのぼって変更されません。このタイプのデータの場合、提供されたタイムゾーンに関係なく、情報を UTC で保存しても情報が失われることはありません。そのため、タイムゾーンを削除します。
将来の長期データ: これらは、十分に遠い将来のイベント、または今後も発生し続けるイベントです。それらが十分に長く保持されている場合、タイムゾーン記述子は変更されることが保証されます。このタイプのデータの良い例は、「The Weekly Management Meeting」です。これは、一度入力され、永続的に機能し続けることが期待されるデータです。これらの値については、それがシステムまたはユーザーによって提供されたものかどうかを判断することが重要です。ユーザー提供のデータの場合、時間は作成者のタイムゾーンで保存する必要があります。それ以外の場合、情報が失われます。この情報の損失は、タイムゾーンの定義が変更され、時間がまったく異なる値として作成者に表示されるときに明らかになります!
Bwooce が指摘したように、作成者と視聴者が異なるタイムゾーンにいる場合、混乱が生じます。その場合、以前の場所からのタイムゾーンのシフトにより、どの時間値が移動したかをアプリケーションが示すことを期待します。
将来の短期データ: これは、すぐに過去のものになるデータ、または短期間しか有効でないデータです。例としては、インターバル タイマー、評価の遷移などがあります。このデータの場合、値の作成時とそれが履歴になる時間との間で定義が変更される可能性は低いため、タイムゾーンを削除することで回避できる可能性があります。しかし、これらの値は「将来の長期的なデータ」になってしまうという悪い癖があることがわかりました。
タイムゾーンを保存することを決定したら、その保存方法に注意する必要があります。
タイムゾーンをオフセットとして保存する場合、タイムゾーンが変更されたらどうしますか? システムを調べて、既存のデータを一括変更しますか? もしそうなら、あなたは今、歴史的な価値を間違ったものにしています。この障害の良い例は、Oracle と iCal です。Oracle はタイムゾーン情報を UTC からのオフセットとして格納し、iCal には作成タイムゾーンの完全な記述子が含まれています。
これにより、既存の値を変更することなく、タイムゾーンの定義を変更できます。タイムゾーン データが変更されると、生成されたインデックスが無効になる可能性があるため、並べ替えがより困難になります。
開発者がタイムゾーンに関係なくすべてを UTC で保存し続けると、タイムゾーン変更の最後のバッチで見られた問題が引き続き発生します。
ある組織では、幹事が夏時間の前にチームのカレンダーを印刷し、変更後に再度印刷する必要がありました。最後に、2 つを比較し、移動したすべての予定を再作成しました。もちろん、彼らはいくつかのミスを犯し、古い夏時間に達して時刻が再び正確になるまで、数週間の苦痛がありました。
上記の Josh は完全に正しいですが、説明しなければならない微妙な警告が 1 つあります。今後のイベントや時間帯については、正解のないケースです。
繰り返しの予定の場合を考えてみましょう。これは GMT 0000 (簡単にするため) で発生します。これは 1200 NZST (ニュージーランド標準時) であり、オーストラリアのシドニーでは 1000 AEST です。
1 つのゾーンで夏時間が有効になると、予定はどうなりますか? それは:
1a. TZ の変更が予定の「所有者」(予約者) のゾーン内にある場合、同じデスク クロック時間 (午前 10:00 など) を維持しようとしますか?
1b. TZ の変更が他の会議出席者のゾーンの 1 つである場合、変更はありません
結果: 所有者 TZ の変更により、予期せず他のすべての人のために移動しますが、所有者に関する限り、「午前 10 時の会議」のままです。
'2. 上と同じですが、逆です。
結果: 会議の所有者に代わって移動します (午前 10 時の会議が午前 9 時の会議、または v/v になります)。これは予想されることですが、不便です。他の参加者が独自の TZ 移行を行うまで、同じデスク クロック時間のままになります。
どちらも完璧ではありません。2 つの予定がある場合を考えてみましょう。1 つは A さんが現地時間の午前 10 時に予約し、もう 1 つは B さんが予約し、A さんが出席者として午前 9 時に発生します。個人 A と個人 B が異なる TZ にいる場合、DST の変更により簡単に二重予約になる可能性があります。
この時点であなたの心が少し曲がっているなら、私はよく理解しています。
この例の背後にあるポイントは、これらの動作のいずれかを適切に行うには、現地時間の UTC バージョンだけでなく、所有者が予約したときにいた TZ (オフセットではない) を知る必要があるということです。それ以外の場合は、オプション 2 を黙って選択するしかありません。GMT 時間は変更されず、プレゼンテーションのみが変更されるため、状況が変更されたことを誰にも通知することもありません...そうですか? (いいえ、これは罠です。午前 10 時の会議が自動的に移動する場合、プレゼンテーションは重要です)
この洞察については、同僚であり友人でもあるジェイソン・ポロックの功績を認めざるを得ません。彼の見解はこちらで、 iCal と VTIMEZONEに関するフォローアップはこちらでお読みください。
すべてを GMT/UTC で保存することは、私にとって最も理にかなっているように思えます。その後、必要なすべてのタイムゾーンで日付と時刻を表示できます。
いくつかの注意事項:
幸いなことに、(.NET) DateTime 型を正しく使用すれば、カレンダーの管理などの厄介な詳細をすべて処理してくれます。その仕組みを理解すれば、これらすべてが非常に簡単になります。
個人的には、すべてを GMT に保存してから、ユーザーのローカル タイムゾーンを使用してユーザーに関連する時刻を表示しない理由がわかりません。
相対時間を表示したい場合は、明らかに時間と翻訳を行う必要がありますが、翻訳を行いたい場合は、GMT が最適なオプションだと思います。
そこで、MSSQL サーバーでちょっとした実験を行いました。
テーブルを作成し、現在のローカライズされたタイムゾーン (オーストラリア) を含む行を追加しました。次に、日時を GMT に変更し、別の行を追加しました。
これらの行が約 10 秒間隔で追加されたとしても、10 時間間隔で SQL サーバーに表示されます。
他に何もないとしても、少なくとも日付を一貫した方法で保存する必要があることを教えてくれます。これは、日付をGMTとして保存するという議論に重みを加えます.
MS Dynamics は GMT を保存し、ユーザー レベルで GMT を基準としたタイム ゾーンを認識します。次に、あなたのタイムゾーンでアイテムを表示します。
それはMSのかなり大きなグループであり、これが彼らがそれを処理することを決定した方法であるため、私はそれをそこに投げ出すと思いました.
ここを見てください。w3c は質問に答える素晴らしい仕事をしました。
ユースケースを見てください。
http://www.w3.org/TR/timezone/
日時を GMT ではなく UTC として保存することを推奨していることに注意してください。GMT は夏時間の影響を受けます。
私はタイムゾーンですべてを保存することを好みます。クライアントは、後で提示する方法を決定できます。私のお気に入りの変換ライブラリはPostgreSQL-Databaseです。
常に GMT (または UTC) で保存します。そこから、任意のローカル タイム ゾーン値に簡単に変換できます。
GMT で保存し、相対的なもの (「約 10 秒前」、「5 か月前」) のみを表示するのが好きです。ほとんどのユースケースでは、ユーザーは実際のタイムスタンプを確認する必要はありません。
例外は確かにあり、個々のアプリケーションには例外が多数ある可能性があるため、「唯一無二」の答えにはなりません。強力な監査能力を必要とするもの (投票など) や、時間が議論の領域の一部であるシステム (天文学、科学研究) では、真のタイムスタンプをユーザーに表示する必要がある場合があります。
ただし、ほとんどのアプリは、単純な相対時間を使用すると理解しやすくなります。
私は通常、Unix 時間を使用します。必ずしも将来的に安全であるとは限りませんが、かなりうまく機能します。