2134

この質問とそれに対する回答を、夏時間、特に実際の切り替えに対処するための決定的なガイドにしたいと考えています。

追加するものがあれば、してください

多くのシステムは、正確な時間を維持することに依存しています。問題は、夏時間による時間の変更 (時計を進めたり遅らせたりすること) にあります。

たとえば、受注システムに、注文の時間に依存するビジネス ルールがあります。時計が変わると、ルールが明確でなくなる可能性があります。注文の時間をどのように保持する必要がありますか? もちろん、無限の数のシナリオがあります。これは単なる例示です。

  • 夏時間の問題にどのように対処しましたか?
  • あなたのソリューションにはどのような仮定が含まれていますか? (ここでコンテキストを探しています)

それほど重要ではありませんが、次のことが重要です。

  • 何を試しましたが、うまくいきませんでしたか?
  • なぜうまくいかなかったのですか?

プログラミング、OS、データの永続性、およびこの問題のその他の関連する側面に興味があります。

一般的な回答は素晴らしいですが、特に 1 つのプラットフォームでしか利用できない場合は、詳細も確認したいと思います。

4

30 に答える 30

1028

回答およびその他のデータの要約:(あなたのものを追加してください)

行う:

  • 正確な瞬間を参照しているときはいつでも、夏時間の影響を受けない統一された標準に従って時間を維持してください。(GMTとUTCはこの点で同等ですが、UTCという用語を使用することをお勧めします。UTCはZuluまたはZ時間とも呼ばれることに注意してください。)
  • 代わりに、現地時間の値を使用して(過去の)時刻を保持することを選択した場合は、タイムスタンプを後で明確に解釈できるように、UTCからのこの特定の時刻の現地時間オフセットを含めます(このオフセットは年間を通じて変更される場合があります)。
  • 場合によっては、UTC時間と同等の現地時間の両方を保存する必要があります。多くの場合、これは2つの別々のフィールドで行われますが、一部のプラットフォームは、datetimeoffset両方を1つのフィールドに格納できるタイプをサポートしています。
  • タイムスタンプを数値として保存する場合は、Unix時間1970-01-01T00:00:00Z(うるう秒を除く)からの秒数を使用します。より高い精度が必要な場合は、代わりにミリ秒を使用してください。この値は、タイムゾーンを調整せずに、常にUTCに基づく必要があります。
  • 後でタイムスタンプを変更する必要がある場合は、元のタイムゾーンIDを含めて、オフセットが記録された元の値から変更されたかどうかを判断できるようにします。
  • 将来のイベントをスケジュールするときは、オフセットが変更されるのが一般的であるため、通常はUTCではなく現地時間が優先されます。 回答ブログ投稿を参照してください。
  • 誕生日や記念日などの日付全体を保存する場合は、UTCまたはその他のタイムゾーンに変換しないでください。
    • 可能な場合は、時刻を含まない日付のみのデータ型で保存してください。
    • このようなタイプが使用できない場合は、値を解釈するときに常に時刻を無視してください。時刻が無視されることが保証されない場合は、その日のより安全な代表時刻として、深夜00:00ではなく正午12:00を選択してください。
  • タイムゾーンオフセットは常に整数時間であるとは限らないことに注意してください(たとえば、インド標準時はUTC + 05:30であり、ネパールはUTC + 05:45を使用します)。
  • Javaを使用している場合は、Java8以降ではjava.timeを使用してください。
  • そのjava.time機能の多くは、 ThreeTen-BackportライブラリのJava6および7にバックポートされています。
  • ThreeTenABPライブラリの初期のAndroid(<26)にさらに適合。
  • これらのプロジェクトは、現在メンテナンスモードになっている由緒あるJoda-Timeに正式に取って代わります。Joda-Time、ThreeTen-Backport、ThreeTen-Extrajava.timeクラス、およびJSR 310は、同じ人であるStephenColebourneによって率いられています。
  • .NETを使用する場合は、 NodaTimeの使用を検討してください。
  • Noda Timeなしで.NETを使用する場合DateTimeOffsetは、多くの場合、それが。よりも優れた選択であると考えてDateTimeください。
  • Perlを使用している場合は、DateTimeを使用してください。
  • Python 3.9以降を使用している場合は、組み込みのzoneinfoを使用してタイムゾーンを操作します。それ以外の場合は、dateutilまたはarrowを使用します。古いpytzライブラリは一般的に回避できます。
  • JavaScriptを使用している場合は、古いmoment.jsまたはmoment-timezoneライブラリを使用しないでください。これらは、アクティブに維持されなくなります。詳細については、Moment.jsプロジェクトのステータスを参照してください。代わりに、Luxondate-fnsday.js、またはjs-jodaを検討してください。
  • PHP> 5.2を使用している場合は、、DateTimeおよびDateTimeZoneクラスによって提供されるネイティブタイムゾーン変換を使用します。使用するときは注意してくださいDateTimeZone::listAbbreviations()-回答を参照してください。PHPを最新のOlsonデータに保つには、timezonedbPECLパッケージを定期的にインストールしてください。答えを参照してください
  • C ++を使用する場合は、 IANAタイムゾーンデータベースを適切に実装するライブラリを使用してください。これらには、cctzICU、およびHowardHinnantの「tz」ライブラリが含まれます。C ++ 20では、後者が標準<chrono>ライブラリに採用されています。
    • タイムゾーンの変換にBoostを使用しないでください。そのAPIは、標準のIANA(別名「zoneinfo」)識別子をサポートすると主張していますが、各ゾーンで行われた可能性のある変更の豊富な履歴を考慮せずに、それらをPOSIXスタイルのデータに大まかにマッピングします。(また、ファイルはメンテナンスから外れています。)
  • Rustを使用する場合は、chronoを使用します。
  • ほとんどのビジネスルールは、UTCやGMTではなく常用時を使用します。したがって、アプリケーションロジックを適用する前に、UTCタイムスタンプをローカルタイムゾーンに変換することを計画してください。
  • タイムゾーンとオフセットは固定されておらず、変更される可能性があることに注意してください。たとえば、歴史的に米国と英国は「スプリングフォワード」と「フォールバック」に同じ日付を使用していました。しかし、2007年に米国は時計が変更される日付を変更しました。これは、1年の48週間、ロンドン時間とニューヨーク時間の差が5時間であり、4週間(春に3回、秋に1回)は4時間であることを意味します。複数のゾーンを含む計算では、このような項目に注意してください。
  • 時間の種類(実際のイベント時間、放送時間、相対時間、履歴時間、繰り返し時間)を考慮して、正しく取得するために保存する必要のある要素(タイムスタンプ、タイムゾーンオフセット、タイムゾーン名)を検討してください。この答え
  • OS、データベース、およびアプリケーションのtzdataファイルを、それらのファイルと他の世界との間で同期させます。
  • サーバーでは、ハードウェアクロックとOSクロックをローカルタイムゾーンではなくUTCに設定します。
  • 前の箇条書きに関係なく、 Webサイトを含むサーバー側のコードは、サーバーのローカルタイムゾーンが特に何かであると決して期待してはなりません。 答えを参照してください
  • 構成ファイルの設定やデフォルトをグローバルに使用するのではなく、アプリケーションコードでケースバイケースでタイムゾーンを操作することをお勧めします。
  • すべてのサーバーでNTPサービスを使用します。
  • FAT32を使用する場合、タイムスタンプはUTCではなく現地時間で保存されることに注意してください。
  • 定期的なイベント(たとえば、毎週のテレビ番組)を処理する場合、時間はDSTによって変化し、タイムゾーンによって異なることに注意してください。
  • 日時の値は、常に下限を含む、上限を除く>=<)としてクエリします。

しないでください:

  • America/New_Yorkなどの「タイムゾーンオフセット」などの「タイムゾーン」と混同しないでください-05:00。それらは2つの異なるものです。タイムゾーンタグwikiを参照してください。
  • ECMAScript 5.1以下には、夏時間を誤って使用する可能性のある設計上の欠陥があるため、 JavaScriptのDateオブジェクトを使用して古いWebブラウザで日付と時刻の計算を実行しないでください。(これはECMAScript 6/2015で修正されました)。
  • クライアントの時計を絶対に信用しないでください。それは非常に間違っている可能性があります。
  • 「どこでも常にUTCを使用する」ように人々に言わないでください。この広範なアドバイスは、このドキュメントの前半で説明したいくつかの有効なシナリオの近視眼的です。代わりに、作業しているデータに適切な時間参照を使用してください。(タイムスタンプはUTCを使用できますが、将来のタイムスケジューリングと日付のみの値は使用しないでください。)

テスト:

  • テストするときは、西半球、東半球、北半球、南半球の国(実際には世界の各四半期、つまり4つの地域)で、DSTが進行中であるかどうか(8を与える)と、実行している国の両方をテストするようにしてください。DSTを使用しないでください(すべての地域をカバーするためにさらに4つ、合計で12になります)。
  • DSTの移行をテストします。つまり、現在夏時間の場合は、冬からの時間値を選択します。
  • タイムゾーンがUTC+12であるなど、DSTを使用して境界ケースをテストし、夏時間の現地時間をUTC + 13にし、冬の現地時間をUTC+13にします。
  • すべてのサードパーティライブラリとアプリケーションをテストし、それらがタイムゾーンデータを正しく処理することを確認します。
  • 少なくとも30分のタイムゾーンをテストします。

参照:

他の:

  • DSTである忌まわしきを終わらせるためにあなたの代表に働きかけなさい。私たちはいつでも期待できます...
  • 地球標準時のロビー
于 2010-03-28T13:01:44.273 に答える
336

上記の回答に何を追加できるかわかりませんが、ここにいくつかのポイントがあります。

時間の種類

考慮すべき 4 つの異なる時期があります。

  1. イベント時間: たとえば、国際的なスポーツイベントが発生した時間、または戴冠式/死など. これは、視聴者ではなく、イベントのタイムゾーンに依存します。
  2. テレビの時間: たとえば、特定のテレビ番組が世界中の現地時間午後 9 時に放送されます。あなたのウェブサイトに(例えばアメリカンアイドルの)結果を公開することを考えるとき重要です
  3. 相対時間: 例: この質問には、21 時間以内に終了する公開報奨金があります。これは表示しやすい
  4. 繰り返される時間: 例: DST が変更された場合でも、毎週月曜日の午後 9 時にテレビ番組が放送されます。

歴史的/別の時間もあります。これらは標準時間にマップされない可能性があるため、煩わしいものです。例: ユリウス暦、土星の太陰暦による日付、クリンゴン暦。

開始/終了タイムスタンプを UTC で保存するとうまくいきます。1 の場合、イベントのタイムゾーン名 + イベントと共に保存されたオフセットが必要です。2 の場合、各地域とともに保存されたローカル時間識別子と、すべての視聴者に対して保存されたローカル タイムゾーン名 + オフセットが必要です (窮地に陥っている場合は、IP からこれを導き出すことができます)。3 の場合、UTC 秒で保存し、タイムゾーンは必要ありません。4 は、グローバル イベントかローカル イベントかに応じて 1 または 2 の特殊なケースですが、このイベントが作成される前後にタイムゾーンの定義が変更されたかどうかを確認できるように、 created atタイムスタンプも保存する必要があります。これは、履歴データを表示する必要がある場合に必要です。

保管時間

  • 時刻を常に UTC で保存する
  • 表示されている現地時間に変換します (ローカル時間は、データを見ているユーザーによって定義されます)。
  • タイムゾーンを保存するときは、名前、タイムスタンプ、およびオフセットが必要です。これが必要になるのは、政府がタイムゾーンの意味を変更することがあるため (例: 米国政府が DST の日付を変更した場合など)、アプリケーションが適切に処理する必要があるためです...かわった。

オフセットと名前

上記の例は次のようになります。

サッカー ワールド カップの決勝戦は、2010 年 7 月 11 日 19:00 UTC に南アフリカ (UTC+2-SAST) で行われました。

この情報を使用すると、南アフリカのタイムゾーンの定義が変更された場合でも、2010 WCS 決勝戦が行われた正確な時刻を歴史的に判断でき、視聴者がデータベースにクエリを実行したときに、ローカル タイムゾーンでそれを表示できます。

システム時刻

また、OS、データベース、およびアプリケーションの tzdata ファイルを相互に同期させ、他の世界と同期させ、アップグレードするときに広範囲にテストする必要があります。依存しているサードパーティのアプリが TZ の変更を正しく処理しなかったということは前代未聞ではありません。

ハードウェア クロックが UTC に設定されていることを確認してください。世界中でサーバーを実行している場合は、OS も UTC を使用するように構成されていることを確認してください。これは、複数のタイムゾーンのサーバーから 1 時間ごとにローテーションされる Apache ログ ファイルをコピーする必要がある場合に明らかになります。ファイル名による並べ替えは、すべてのファイルの名前が同じタイムゾーンである場合にのみ機能します。また、あるボックスから別のボックスに ssh してタイムスタンプを比較する必要があるときに、頭の中で日付計算を行う必要がないことも意味します。

また、すべてのボックスで ntpd を実行します。

クライアント

クライアント マシンから取得したタイムスタンプが有効であると決して信頼しないでください。たとえば、Date: HTTP ヘッダー、または JavaScriptDate.getTime()呼び出しです。これらは、不透明な識別子として使用する場合、または同じクライアントで単一のセッション中に日付計算を行う場合には問題ありませんが、サーバー上にあるものとこれらの値を相互参照しようとしないでください。クライアントは NTP を実行しておらず、BIOS クロック用のバッテリが動作しているとは限りません。

トリビア

最後に、政府は非常に奇妙なことをすることがあります。

オランダの標準時は、1909 年 5 月 1 日から 1937 年 6 月 30 日まで、法律により UTC より正確に 19 分 32.13 秒進んでいました。このタイム ゾーンは、HH:MM 形式を使用して正確に表すことはできません。

わかりました、私は終わったと思います。

于 2010-07-16T22:40:29.303 に答える
91

これは重要かつ驚くほど難しい問題です。真実は、永続的な時間について完全に満足できる基準がないということです。たとえば、SQL 標準と ISO 形式 (ISO 8601) では明らかに十分ではありません。

概念的な観点から、通常は 2 種類の日時データを扱いますが、それらを区別すると便利です (上記の標準では区別されません): 「物理時間」と「常用時間」。

「物理的な」時間の瞬間は、物理学が扱う連続的な普遍的なタイムライン内のポイントです (もちろん、相対性は無視されます)。この概念は、たとえば、UTC で適切にコード化して永続化できます (うるう秒を無視できる場合)。

「市民の」時間は、市民の規範に従う日時指定です。ここでの時間は、一連の日時フィールド (Y、M、D、H、MM、S、FS) と TZ (タイムゾーン指定) によって完全に指定されます。 (実際には「カレンダー」でもありますが、議論をグレゴリオ暦に限定すると仮定しましょう)。タイムゾーンとカレンダーを併用すると、(原則として) ある表現から別の表現へのマッピングが可能になります。しかし、常用時刻と物理時刻は根本的に異なるタイプのマグニチュードであり、概念的に分離し、異なる方法で処理する必要があります (類推: バイト配列と文字列)。

この問題は混乱を招きます。なぜなら、私たちはこれらのタイプの出来事を同じ意味で話しているからです。問題 (およびこれらの概念を区別する必要性) は、将来のイベントでより明らかになります。例(ここでの私の議論から取られました。

2019-Jul-27, 10:30:00John は、 datetime 、 TZ=にあるイベントのリマインダーをカレンダーに記録します Chile/Santiago(オフセット GMT-4 があるため、 UTC に対応し2019-Jul-27 14:30:00ます)。しかし、将来のある日、国は TZ オフセットを GMT-5 に変更することを決定します。

さて、その日が来たら...そのリマインダーがトリガーされるはずです

A) 2019-Jul-27 10:30:00 Chile/Santiago = UTC time 2019-Jul-27 15:30:00?

また

B) 2019-Jul-27 9:30:00 Chile/Santiago = UTC time 2019-Jul-27 14:30:00?

ジョンがカレンダーに「電話してください」と言ったときに概念的に何を意味していたのかを理解していない限り、正解はありません2019-Jul-27, 10:30:00 TZ=Chile/Santiago

彼は「市民の日時」(「私の街の時計が 10:30 を示しているとき」) を意味していたのでしょうか? その場合、A)が正解です。

それとも、彼は「物理的な瞬間」、つまり私たちの宇宙の時間の連続線のポイント、つまり「次の日食が起こるとき」を意味したのでしょうか. その場合、答え B) が正しいものです。

いくつかの日付/時刻 API は、この区別を正しく行っています。そのうちのJodatimeは、次の (3 番目の!) Java DateTime API (JSR 310) の基盤です。

于 2010-03-28T15:17:33.667 に答える
63

懸念事項を構造的に明確に分離する - どの層がユーザーと対話し、正規表現 (UTC) の日時を変更する必要があるかを正確に把握します。非 UTC 日時はプレゼンテーション(ユーザーのローカル タイムゾーンに従います) であり、UTC 時間はモデルです(バックエンド層と中間層で一意のままです)。

また、実際の視聴者は何か、サービスを提供する必要がないものは何か、どこに線を引くかを決定します。実際に重要な顧客がいて、その地域専用の別のユーザー向けサーバーを検討しない限り、エキゾチックなカレンダーには触れないでください。

ユーザーの場所を取得して維持できる場合は、場所を使用して体系的な日時変換 (.NET カルチャや SQL テーブルなど) を行いますが、ユーザーにとって日時が重要な場合は、エンド ユーザーがオーバーライドを選択できるようにします。

関連する過去の監査義務がある場合(アリゾナ州のジョーが 2 年前の 9 月にいつ請求書を支払ったかを正確に伝えるなど) 、記録のためにUTC と現地時間の両方を保持します (変換テーブルは時間の経過とともに変化します)。

ファイル、Web サービスなど、大量に発生するデータの時間参照タイム ゾーンを定義します。たとえば、東海岸の会社が CA にデータ センターを持っているとします。どちらか一方を想定するのではなく、標準として何を使用しているかを尋ねて知る必要があります。

日時のテキスト表現に埋め込まれたタイムゾーン オフセットを信頼せず、それらの解析と追跡を受け入れません。代わりに、タイム ゾーンおよび/または参照ゾーンを明示的に定義する必要があることを常に要求します。PST オフセットを使用して簡単に時刻を取得できますが、実際の時刻は EST です。これはクライアントの参照時刻であり、PST にあるサーバーでレコードがエクスポートされたばかりであるためです。

于 2010-08-04T10:52:41.817 に答える
41

ftp://elsie.nci.nih.gov/pubhttp://iana.org/time-zones/から入手できるOlsontzデータベースについて知る必要があります。これは、世界中のさまざまな国で冬と夏(標準および日光の節約)の時間を切り替える時期(およびかどうか)の土壇場での変更に対処するために、年に複数回更新されます。2009年の最後のリリースは2009年代でした。2010年には、2010nでした。2011年は2011nでした。2012年5月末のリリースは、2012cでした。2つの別々のアーカイブ(tzcode20xxy.tar.gzとtzdata20xxy.tar.gz)に、データと実際のタイムゾーンデータ自体を管理するための一連のコードがあることに注意してください。コードとデータの両方がパブリックドメインにあります。

これは、America / Los_Angeles(およびUS / Pacificなどの同義語)などのタイムゾーン名のソースです。

さまざまなゾーンを追跡する必要がある場合は、Olsonデータベースが必要です。他の人がアドバイスしているように、データを固定形式(通常はUTCが選択されます)で、データが生成されたタイムゾーンのレコードとともに保存することもできます。その時点でのUTCからのオフセットとタイムゾーン名を区別したい場合があります。それは後で違いを生むことができます。また、現在2010-03-28T23:47:00-07:00(米国/太平洋)であることを知っていると、値2010-11-15T12:30の解釈に役立つ場合と役に立たない場合があります。これはおそらくPSTで指定されています( PDT(太平洋夏時間)ではなく、太平洋標準時)。

標準のCライブラリインターフェイスは、この種のものではひどく役に立ちません。


オルソンのデータは移動しました。これは、ADオルソンが間もなく廃止されることと、著作権侵害を理由にメンテナに対して(現在は却下された)訴訟があったためです。タイムゾーンデータベースは現在、Internet Assigned Numbers AuthorityであるIANAの支援の下で管理されており、フロントページに「タイムゾーンデータベース」へのリンクがあります。ディスカッションメーリングリストは現在tz@iana.org; アナウンスリストはtz-announce@iana.orgです。

于 2010-03-29T06:50:15.260 に答える
27

一般に、保存されたタイムスタンプに現地時間オフセット (DST オフセットを含む) を含めます。後でタイムスタンプを元のタイムゾーン (および DST 設定) で表示したい場合、UTC だけでは十分ではありません。

オフセットは常に整数の時間数ではないことに注意してください (たとえば、インド標準時は UTC+05:30 です)。

たとえば、適切な形式はタプル (UNIX 時間、分単位のオフセット) またはISO 8601です。

于 2010-03-28T14:59:06.357 に答える
24

「コンピューターの時間」と「人の時間」の境界を越えることは悪夢です。主な問題は、タイムゾーンと夏時間を管理するルールに標準のようなものがないことです。国は、タイムゾーンと DST 規則をいつでも自由に変更できます。

イスラエル、ブラジルなどの一部の国では、毎年サマータイムをいつ実施するかを決定しているため、DST がいつ実施されるかを事前に知ることは不可能です。他の人は、DSTがいつ有効になるかについて固定された(っぽい)ルールを持っています. 他の国では、DST はまったく使用されていません。

タイムゾーンは、GMT との完全な時間差である必要はありません。ネパールは+5.45です。+13 のタイムゾーンもあります。つまり、次のことを意味します。

SUN 23:00 in Howland Island (-12)
MON 11:00 GMT 
TUE 00:00 in Tonga (+13)

すべて同じ時間ですが、3 つの異なる日です。

タイムゾーンの略語についても明確な基準がなく、DST でどのように変化するかは次のようになります。

AST Arab Standard Time     UTC+03
AST Arabian Standard Time  UTC+04
AST Arabic Standard Time   UTC+03

最善のアドバイスは、可能な限り現地時間から離れ、できる限り UTC に固執することです。可能な限り最後の瞬間にのみ現地時間に変換してください。

テストするときは、西半球と東半球の国をテストし、DST が進行中の場合とそうでない場合の両方と、DST を使用しない国 (合計 6 つ) をテストしてください。

于 2010-03-29T14:02:26.577 に答える
20

設計で対応できる場合は、現地時間の変換をまとめて回避してください。

これは非常識に聞こえるかもしれませんが、UX について考えてみてください。ユーザーは、絶対的な日付 (2010.09.17、9 月 17 日金曜日) よりも、近い相対的な日付 (今日、昨日、次の月曜日) を一目で処理します。さらに考えてみると、日付が に近づくほどタイムゾーン (および DST) の精度が重要にnow()なるため、日付/日時を +/- 1 または 2 週間の相対形式で表すことができれば、残りの日付は UTC にすることができ、ユーザーの 95% にとってあまり重要ではありません。

このようにして、すべての日付を UTC で保存し、UTC で相対比較を行い、単純に相対日付のしきい値の範囲外のユーザー UTC 日付を表示できます。

これは、ユーザー入力にも適用できます (ただし、一般的にはより制限された方法で)。{ 昨日、今日、明日、次の月曜日、次の木曜日 } のみを含むドロップダウンからの選択は、日付ピッカーよりもはるかにシンプルで簡単です。日付ピッカーは、フォーム入力の最も苦痛を引き起こすコンポーネントの一部です。もちろん、これはすべてのケースで機能するわけではありませんが、少し巧妙な設計を行うだけで非常に強力になることがわかります。

于 2010-09-17T06:24:45.367 に答える
16

最近、Web アプリケーションで問題が発生しました。Ajax ポストバックで、サーバー側のコードに返される日時が、提供された日時とは異なります。

JavaScript はタイム ゾーンと夏時間に合わせて調整し、一部のブラウザーでは夏時間を適用するタイミングを計算していたため、文字列としてクライアントにポストバックする日付を作成したクライアントの JavaScript コードに関係していた可能性が最も高いです。他とは違うようでした。

最後に、クライアントでの日付と時刻の計算を完全に削除することを選択し、サーバー上で日付時刻に変換された整数キーでサーバーにポストバックして、一貫した変換を可能にしました。

これから学んだこと: 絶対に必要な場合を除き、Web アプリケーションで JavaScript の日付と時刻の計算を使用しないでください。

于 2010-03-28T13:07:46.503 に答える
16

私は試したことはありませんが、タイム ゾーンを調整する方法としては、次のような方法が有効だと思います。

  1. すべてを UTC で保存します。

  2. TZOffsetsRegionClassId、StartDateTime、OffsetMinutes (int、分単位) の 3 つの列を持つテーブルを作成します。

テーブルに、現地時間が変更された日付と時刻のリストと、その程度を格納します。テーブル内の地域の数と日付の数は、サポートする必要がある日付の範囲と世界の地域によって異なります。日付には実用的な限界まで未来を含める必要がありますが、これは「歴史的な」日付であるかのように考えてください。

UTC 時間のローカル時間を計算する必要がある場合は、次のようにします。

SELECT DATEADD('m', SUM(OffsetMinutes), @inputdatetime) AS LocalDateTime
FROM   TZOffsets
WHERE  StartDateTime <= @inputdatetime
       AND RegionClassId = @RegionClassId;

このテーブルをアプリにキャッシュし、データベースにアクセスするのではなく、LINQ または同様の手段を使用してクエリを実行することをお勧めします。

このデータは、パブリック ドメインの tz データベースから抽出できます。

このアプローチの利点と脚注:

  1. コードにルールが組み込まれていないため、新しい地域や日付範囲のオフセットを簡単に調整できます。
  2. 日付や地域のすべての範囲をサポートする必要はありません。必要に応じて追加できます。
  3. 地域は地政学的な境界に直接対応する必要はなく、行の重複を避けるために (たとえば、米国のほとんどの州は DST を同じ方法で処理します)、別のテーブルでより伝統的なリストにリンクする広範な RegionClass エントリを作成できます。州、国など
  4. 過去数年間で DST の開始日と終了日が変更された米国のような状況では、これは非常に簡単に対処できます。
  5. StartDateTime フィールドには時刻も格納できるため、午前 2 時の標準的な切り替え時間は簡単に処理されます。
  6. 世界中のどこでも 1 時間の DST が使用されているわけではありません。これにより、これらのケースを簡単に処理できます。
  7. データ テーブルはクロスプラットフォームであり、ほぼすべてのデータベース プラットフォームまたはプログラミング言語を使用する開発者が使用できる独立したオープン ソース プロジェクトになる可能性があります。
  8. これは、タイム ゾーンとは関係のないオフセットに使用できます。たとえば、地球の自転を調整するために時々発生する 1 秒の調整、グレゴリオ暦への、およびグレゴリオ暦内での歴史的な調整などです。
  9. これはデータベース テーブル内にあるため、標準的なレポート クエリなどで、ビジネス ロジック コードを介さずにデータを利用できます。
  10. これは、必要に応じてタイム ゾーン オフセットも処理し、地域が別のタイム ゾーンに割り当てられた特殊な歴史的ケースを説明することもできます。必要なのは、最小の開始日で各地域にタイム ゾーン オフセットを割り当てる最初の日付だけです。これには、タイム ゾーンごとに少なくとも 1 つの地域を作成する必要がありますが、次のような興味深い質問をすることができます。(一方の SUM() を他方から減算するだけです)。

現在、このアプローチまたは他のアプローチの唯一の欠点は、現地時間からGMT への変換が完全ではないことです。これは、クロックに対して負のオフセットを持つ DST の変更は、特定の現地時間を繰り返すためです。これに対処する簡単な方法はありません。これが、そもそも現地時間を保存することが悪いニュースである理由の 1 つです。

于 2010-03-28T15:08:15.673 に答える
14

これは、「シフト計画システム (工場労働者など)」と「ガス依存管理システム」の 2 種類のシステムで当てはまりました…</p>

1 日 23 時間と 25 時間の長さは対処するのが苦痛であり、7 時間または 9 時間かかる 8 時間のシフトも同様です。問題は、各顧客、または顧客の部門でさえ、これらの特別なケースで何をするかについて作成した (多くの場合文書化せずに) 異なるルールを持っていることに気付くことです。

いくつかの質問は、顧客が「既製の」ソフトウェアの代金を支払うまで尋ねない方がよい場合があります。ソフトウェアを購入する際に、この種の問題を前もって考えている顧客を見つけることは非常にまれです。

すべての場合において、日付/時刻を保存する前に、UTC で時刻を記録し、現地時間との間で変換する必要があると思います。ただし、夏時間とタイムゾーンでは、特定の時間がどの時間帯にあるかを知ることさえ難しい場合があります。

于 2010-03-28T14:36:00.803 に答える
13

Webの場合、ルールはそれほど複雑ではありません...

  • サーバー側、UTCを使用
  • クライアント側、Olsonを使用
    • 理由:UTCオフセットは夏時間に安全ではありません(たとえば、ニューヨークは1年の一部でEST(UTC-5時間)、残りの年はEDT(UTC-4時間)です)。
    • クライアント側のタイムゾーンを決定するには、次の2つのオプションがあります。

残りは、サーバー側の日時ライブラリを使用したUTC/ローカル変換です。行ってもいい...

于 2012-08-14T15:25:47.933 に答える
13

Web サイトやその他のバックエンド サービスなど、サーバー上で実行されるアプリケーションに関しては、アプリケーションはサーバーのタイム ゾーン設定を無視する必要があります。

一般的なアドバイスは、サーバーのタイム ゾーンを UTC に設定することです。これは確かに優れたベスト プラクティスですが、他のベスト プラクティスに従わないアプリケーションの応急処置として存在します。たとえば、サービスが UTC ベースのタイムスタンプではなくローカルのタイムスタンプを使用してログ ファイルに書き込みを行っている可能性があるため、夏時間へのフォールバック移行中にあいまいさが生じます。サーバーのタイム ゾーンを UTC に設定すると、そのアプリケーションが修正されます。ただし、実際の修正は、アプリケーションが最初に UTC を使用してログを記録することです。

Web サイトを含むサーバー側のコードは、サーバーのローカル タイム ゾーンが特定のものであることを期待してはなりません。

一部の言語では、ローカル タイム ゾーンがアプリケーション コードに簡単に侵入する可能性があります。たとえば、.NET のメソッドはローカル タイム ゾーンからUTC にDateTime.ToUniversalTime変換し、プロパティはローカル タイム ゾーンで現在の時刻を返します。また、JavaScript のコンストラクターはコンピューターのローカル タイム ゾーンを使用します。このような例は他にもたくさんあります。コンピュータのローカル タイム ゾーン設定を使用するコードを避けて、防御的なプログラミングを実践することが重要です。DateTime.NowDate

デスクトップ アプリケーション、モバイル アプリケーション、クライアント側 JavaScript などのクライアント側コードのローカル タイム ゾーンを使用して予約します。

于 2015-06-17T16:27:35.283 に答える
11

サーバーをUTCに設定したままにし、すべてがntpまたは同等のものに構成されていることを確認します。

UTCは夏時間の問題を回避し、非同期サーバーは診断に時間がかかる予測できない結果を引き起こす可能性があります。

于 2010-03-28T14:32:08.537 に答える
9

FAT32ファイルシステムに保存されているタイムスタンプを処理するときは注意してください。タイムスタンプは常に現地時間の座標で保持されます(DSTを含む-msdnの記事を参照)。あれにやけどを負った。

于 2010-08-04T17:29:37.050 に答える
7

もう1つ、サーバーに最新の夏時間パッチが適用されていることを確認してください。

昨年、UTC ベースのシステムを使用していたにも関わらず、北米のユーザーの場合、3 週間にわたって一貫して 1 時間遅れるという状況がありました。

結局、それはサーバーであることが判明しました。最新のパッチを適用する必要がありました ( Windows Server 2003 )。

于 2010-08-04T11:08:29.740 に答える
6

PHPのDateTimeZone::listAbbreviations()出力

この PHP メソッドは、いくつかの「主要な」タイムゾーン (CEST など) を含む連想配列を返します。これには、より具体的な「地理的」タイムゾーン (ヨーロッパ/アムステルダムなど) が含まれます。

これらのタイムゾーンとそのオフセット/DST 情報を使用している場合は、次のことを認識することが非常に重要です。

各タイムゾーンのすべての異なるオフセット/DST 構成(過去の構成を含む) が含まれているようです!

たとえば、Europe/Amsterdam は、この関数の出力で 6 回見つかります。2 つのオカレンス (オフセット 1172/4772) は、1937 年まで使用されていたアムステルダム時間用です。2 つ (1200/4800) は 1937 年から 1940 年の間に使用されたものです。2 つ (3600/4800) は 1940 年以降に使用された時間用です。

したがって、この関数によって返されたオフセット/DST 情報が現在正しい/使用中であると信頼することはできません!

特定のタイムゾーンの現在のオフセット/DST を知りたい場合は、次のようにする必要があります。

<?php
$now = new DateTime(null, new DateTimeZone('Europe/Amsterdam'));
echo $now->getOffset();
?>
于 2014-01-17T23:56:26.940 に答える
5

DST をアクティブにして実行しているデータベース システムを維持している場合は、秋の移行中にシャットダウンする必要があるかどうかを慎重に確認してください。Mandy DBS (または他のシステムも同様) は、(ローカル) 時間の同じポイントを 2 回通過することを好みません。これは、秋に時計を戻すときに起こることです。SAPはこれを(IMHO本当にきちんとした)回避策で解決しました-時計を元に戻す代わりに、内部時計を通常の半分の速度で2時間実行させました...

于 2010-03-28T15:41:38.560 に答える
4

ビジネスルールは常に常用時に機能する必要があります(別の言い方をする法律がない限り)。常用時は混乱していることに注意してください、しかしそれは人々が使うものなので、それは重要なことです。

内部的には、タイムスタンプをエポックからの常用時秒のようなものに保ちます。エポックは特に重要ではありませんが(私はUnixエポックを好みます)、他の方法よりも簡単になります。うるう秒が本当に必要なこと(衛星追跡など)を行わない限り、うるう秒は存在しないふりをします。タイムスタンプと表示時間の間のマッピングは、DSTルールを適用する必要がある唯一のポイントです。ルールは頻繁に変更されるため(グローバルレベルでは、年に数回、政治家のせいになります)、マッピングをハードコーディングしないようにする必要があります。オルソンのTZデータベースは非常に貴重です。

于 2010-03-28T11:47:20.303 に答える
4

.NETでこれに苦労している人はDateTimeOffset、 and/orを使用TimeZoneInfoする価値があるかどうかを確認してください。

IANA/Olson タイム ゾーンを使用したい場合、または組み込み型ではニーズに不十分であることがわかった場合は、.NET 用のよりスマートな日付と時刻 API を提供するNoda Timeを確認してください。

于 2012-09-13T19:40:03.913 に答える
4

.NET フレームワークを使用していますか? もしそうなら、.NET 3.5 で追加されたDateTimeOffset型を紹介させてください。

この構造体は、インスタンスの日付と時刻と協定世界時 (UTC) との差を指定する とDateTimeオフセット ( ) の両方を保持します。TimeSpanDateTimeOffset

  • DateTimeOffset.Now静的メソッドは、現在の (ローカル) 時間とローカル オフセット (オペレーティング システムの地域情報で定義されている) で構成されるインスタンスを返しますDateTimeOffset

  • DateTimeOffset.UtcNow静的メソッドは、(グリニッジにいるかのように) UTC の現在時刻で構成されるインスタンスを返し ますDateTimeOffset

その他の便利なタイプは、TimeZoneクラスとTimeZoneInfoクラスです。

于 2011-12-29T12:32:09.390 に答える
2

不正確または少なくとも紛らわしいと思われる2つのことを指摘したかっただけです。

夏時間の影響を受けない統一された標準に従って、常に時間を維持します。UTCが最も頻繁に言及されているようですが、GMTとUTCは異なる人々によって言及されています。

(ほぼ)すべての実用的なコンピューティング目的では、UTCは実際にはGMTです。小数秒のタイムスタンプが表示されない限り、GMTを処理しているため、この区別は冗長になります。

タイムスタンプを保存するときは、現地時間オフセット(DSTオフセットを含む)をそのまま含めます。

タイムスタンプは常にGMTで表されるため、オフセットはありません。

于 2011-10-18T09:46:28.817 に答える
2

YouTubeの Computerphile チャンネルにあるTom Scott のタイムゾーンに関するビデオにも、このトピックに関する素晴らしく面白い説明があります。例は次のとおりです。

  • サモア(太平洋の島) は、オーストラリアとニュージーランドとの取引を容易にするためにタイムゾーンを 24 時間進めます。
  • ウェスト バンクでは、2 つの人口集団が異なるタイム ゾーンに従っています。
  • 18 世紀にユリウス暦からグレゴリオ 暦に変更されます (ロシアでは 20 世紀に起こりました)。
于 2016-02-19T11:21:58.337 に答える
1

実際、kernel32.dll は SystemTimeToTzSpecificLocation をエクスポートしません。ただし、次の 2 つをエクスポートします: SystemTimeToTzSpecificLocalTime と TzSpecificLocalTimeToSystemTime...

于 2011-09-29T16:57:31.410 に答える
1
  • UTC オフセット (またはタイム ゾーンへの参照) なしでローカル タイムを保存しないでください。これを行わない方法の例には、FAT32 や C が含まれますstruct tm¹。
  • タイムゾーンは以下の組み合わせであることを理解する
    • UTC オフセットのセット (例: 冬は +0100、夏は +0200)
    • 切り替えがいつ発生するかに関するルール (時間の経過とともに変更される可能性があります。たとえば、1990 年代に EU は切り替えを 3 月と 10 月の最終日曜日の 02:00 標準時間/03:00 DST とするように調整しました。以前はこれは異なっていました)加盟国間)。

¹ の一部の実装でstruct tmは UTC オフセットが保存されますが、これは標準にはなっていません。

于 2018-02-02T21:24:46.677 に答える
1

次のようなコンストラクターだけに依存しないでください

 new DateTime(int year, int month, int day, int hour, int minute, TimeZone timezone)

DST のために特定の日時が存在しない場合、例外をスローできます。代わりに、そのような日付を作成するための独自のメソッドを作成してください。それらの中で、DST が原因で発生する例外をキャッチし、移行オフセットで必要な時間を調整します。DST は、タイムゾーンに応じて、異なる日付と異なる時間 (ブラジルの場合は真夜中であっても) に発生する場合があります。

于 2012-05-19T10:19:34.333 に答える
-4

データベース(特にMySQLですが、これはほとんどのデータベースに当てはまります)を扱う際に、UTCを保存するのが難しいことがわかりました。

  • データベースは通常、デフォルトでサーバーの日時(つまり、CURRENT_TIMESTAMP)で動作します。
  • サーバーのタイムゾーンを変更できない場合があります。
  • タイムゾーンを変更できる場合でも、サーバーのタイムゾーンがローカルであることを期待するサードパーティのコードがある可能性があります。

サーバーの日時をデータベースに保存してから、SQLステートメントでデータベースに保存された日時をUTC(つまり、UNIX_TIMESTAMP())に変換させる方が簡単であることがわかりました。その後、コードで日時をUTCとして使用できます。

サーバーとすべてのコードを100%制御できる場合は、サーバーのタイムゾーンをUTCに変更することをお勧めします。

于 2011-12-13T11:09:33.077 に答える