4

この質問には、テストコードを書くことで答えることができたと思います。私は怠け者ではありません、私は答えが一般的に役立つかもしれないと思っただけです。

(NOWルーチンによって返される)現地時間でスタンプされたレコードを使用して大量のデータを生成したアプリがあります。夏時間の内外で移行する問題が発生しました。つまり、DSTに変更すると1時間が失われ、DSTを終了すると1時間が繰り返されます。これにより、日付順のレコードを想定した操作で問題が発生します。

そのため、アプリはUTCのすべての日時で機能するように変更されましたが、UTCまたは現地時間で日時を表示する機能があります。また、現地時間で保存された日時を処理し、UTCに正しくシフトされていることを確認する必要があります。DSTが有効な間に日時が保存された可能性があるため、これは注意が必要です。したがって、一般的なケースでは、ランダムな日付がDST期間内か外かを判断できる必要があります。もちろん、日時があいまいで、夏時間が終了する前の最後の1時間、または終了後の最初の1時間になる可能性がある1時間の期間があります。これを解決する方法はありません。

変更をコーディングする際に、NOW呼び出しの結果について疑問に思いました。内部的にはGetLocalTimeを呼び出します。DST期間内にあるが、「夏時間の変更に合わせて時計を調整する」オプションがオフになっている場合、GetLocalTime(およびNOW)は何を返しますか?

「夏時間の変更に合わせて時計を調整する」がオフかオンかに関係なく、(DSTバイアスが適用された)DST期間内の現在の日時を返すルーチンを作成するにはどうすればよいですか。

4

2 に答える 2

4

問題を簡単に解決できるとは思いません。
変数が多すぎます:

  • 保存されたタイムスタンプ
  • 現在のタイムゾーン
  • 常に変化するタイムゾーンルール
  • これらのタイムゾーンルールが、使用するすべての機器で正確であることの確認(つまり、全員が常にパッチを適用している)
  • あなたの時計の不正確さ

タイムゾーンルールを支援できるDelphiTZDBプロジェクトがあります。

上記のすべての変数に依存するのではなく、次の3つのフィールドを格納する方がはるかに実用的だと思います。

  • ローカル形式のタイムスタンプ
  • 現在のタイムゾーン
  • UTC形式のタイムスタンプ

3番目のフィールドと、表示する最初の2つのフィールドで並べ替えを実行します。

--jeroen

于 2011-01-12T10:57:27.530 に答える
2

TzSpecificLocalTimeToSystemTime(およびその明らかな逆)を使用します。これらを使用すると、ローカルの日付/時刻で有効な夏時間設定に基づいて、UTCとローカルの日付/時刻の間で変換できます。XPより前のバージョンでアプリを実行する場合は、「delayed」関数属性を使用してこれを(kernel32から)ロードします。

function TzSpecificLocalTimeToSystemTime(lpTimeZoneInformation: PTimeZoneInformation;
  var lpLocalTime, lpUniversalTime: TSystemTime): BOOL; stdcall;

function TzSpecificLocalTimeToSystemTime; external kernel32 name 'TzSpecificLocalTimeToSystemTime' delayed;
于 2011-01-12T14:08:58.570 に答える