私はいくつかのタイムゾーンで動作するはずのc ++プロジェクトを作成しています。アプリケーションは基準タイムゾーンのあるイベントを受け取り、このイベントはユーザーのローカルタイムゾーンで正しい時間にユーザーにグラフィカルに表示されます。たとえば、ベルリンで働いているユーザーが東京で書かれたイベントを受け取ります。東京からのイベントは、最初にUTC時間に変換され、次にUTCからベルリンのコンピューター現地時間に再変換され、最後にユーザーのグラフィカルインターフェイスに表示されます。
UTCからローカルコンピュータ時間に変換するために、私はWindows APIのいくつかの機能を自由に使用して仕事をすることができます。しかし、時間を別のタイムゾーンからUTCに変換するには、Windowsレジストリからタイムゾーン情報を取得する必要があります。
現在、一部のタイムゾーンには考慮すべき夏時間があります。 Windowsの情報から問題なく繰り返しルールを作成できます。しかし、DSTが発生するはずの日がいくつかのタイムゾーンで時々正しくないことに気づきました。たとえば、「E。南アメリカ標準時」。 Windowsが提供する繰り返しにより、DSTの開始日は1週間早く始まります。
私が正しく理解している場合、この特定のタイムゾーンに対してWindowsによって返される繰り返しルールは、「毎年、2か月目、1か月の2週目」を示しています。ただし、このルールがインターネット上で公開された正しい日付に変更されることはほとんどありませんが、ルールが「毎年、2か月目、3週目の3週目」である場合、日付はすべて正しいです。さらに、提供されたスクリーンショットで確認できるように、Windowsレジストリデータには、DSTの開始時刻が2週間(青で強調表示)されていますが、DSTの終了時刻が3週間(赤で囲まれています)と表示されています。 。データコンテンツの説明はここにあります: http://msdn.Microsoft.com/en-us/library/windows/desktop/ms725481(v = vs.85).aspx
いくつか質問があります
[〜#〜]注[〜#〜]このメッセージを投稿する前に、レジストリから読み取ったデータが正しいかどうかを強く確認しました。私はそれがこのタイプのエラーではないことを確信しています。
[〜#〜]注[〜#〜]Windows 7を使用していますが、Windows 10でも問題は同じです
Windowsタイムゾーンデータに大きく関与しているMicrosoftの従業員として、MicrosoftがWindowsタイムゾーンデータをできる限り正確に保つために更新をリリースすることを保証するために懸命に取り組んでいることを保証させてください。
タイムゾーンの変更のタイミング を含むいくつかの課題があります。たとえば、最近 フィジー、キプロス、スーダン、トンガ、ナミビア、タークスカイコスでのWindowsタイムゾーンの変更についての通知を投稿しました 。場合によっては、これらのさまざまな政府によって確立された発効日を満たすことができます。十分なリードタイムがないためにできない場合もあります。
2017年11月1日発効の変更について 2017年10月17日にIANA tzメーリングリスト に告げた最近のスーダンの事例を考えてみてください。IANAはこの変更を処理しており、Microsoftもそうです。ただし、Windowsタイムゾーンデータに新しい"Sudan Standard Time"
タイムゾーンが作成されるまでには、短い通知とWindowsオペレーティングシステムでのこのような変更の処理に時間がかかるため、少し時間がかかります。したがって、当面は別のタイムゾーンを使用するよう暫定的なガイダンスを発行し、影響を受ける地域の時間の全履歴を適切に反映するデータが得られたら元に戻します。
あなたが言及したWindowsタイムゾーン"E. South America Standard Time"
に関して、タイムゾーンデータは正しいです。レジストリエントリを展開すると、「Dynamic DST」と呼ばれるサブキーがあり、データには年ごとの変更が含まれています。一部のタイムゾーンでは、これはまったく必要ありません。同じルールが毎年繰り返されるため、他のタイムゾーンでは非常に少量のデータが表示されます。ただし、ブラジルの場合は、2009年から2040年までの動的DSTエントリに気付くでしょう。
(画像をクリックして完全な解像度を確認し、手動で赤でマークした領域が前年比で変化していることに注意してください)
ダイナミックDSTエントリは、Win32 DYNAMIC_TIME_ZONE_INFORMATION
構造、およびGetDynamicTimeZoneInformation
などの名前に「ダイナミック」が含まれる対応するAPIをサポートします。 (これらは.NET FrameworkのSystem.TimeZoneInfo
クラスもサポートします。)これらのAPIのほとんどはWindows Vista/Server 2008以降に配置されており、他のいくつかはWindows 7/Server 2012で提供されています。
親キーにあるTZI
エントリは、Windowsの内部プロセスによって、今年の動的ルールからコピーされることに注意してください。これは、Windows 2000以降に導入されているWin32 TIME_ZONE_INFORMATION
構造体で動作するAPIをサポートしています。
あなたが尋ねた特定の質問に答えるには:
繰り返しルールを正しく理解しましたか?
あなたが引用した特定のルールは2017年のみのものであり、DSTは第2月(2月)、第3土曜日の23に終了します。現地時間59:59.999、10月(10月)の第2土曜日の現地時間23:59:59.999に再び開始されます。ブラジルは南半球にあるため、夏時間は1年の終わりに始まり、翌年の初めに終わります。
また、なぜ日曜日の00:00:00.000ではなく土曜日の23:59:59.999なのか疑問に思われるかもしれません。これは歴史の産物です。過去には、遷移を評価するために<=
ではなく<
を誤って使用し、その結果、クロックを誤って1ミリ秒、翌日に戻し、その後に戻す特定のプログラムおよびプロセスがありました。再びそれに戻ります。誤って変化する日によって生成されたイベントは、さらに問題を引き起こす可能性があります。マイクロソフトはこれらのバグを修正するために最善を尽くしましたが、ある日新しい場所で問題が発生するリスクを負う代わりに、1msオフにすることを選択しました。 (これは、真夜中に発生する遷移にのみ適用されます。)
いくつかのタイムゾーン、特に「E.南アメリカ標準時」に関する既知の問題はありますか?
そのタイムゾーンの既知の問題はありませんが、Windowsタイムゾーン(動的DSTデータを使用した場合でも)は、1年間に最大2つのタイムゾーンの移行しかサポートできないという既知の問題があります。したがって、モロッコのような場所では 1年に4回移行currentタイムゾーンを維持するいくつかの内部回避策があります「現在」が現地時間の正確な表現であるように同期されたデータ。ただし、任意の時点で年間のすべてのポイントを正しく表すことはできません。
また、現在 Troll Station、Antarctica に完全に対応するタイムゾーンもありません。その理由は、2005年から2015年にかけて、この 研究ステーション (50歳未満の人口)が毎年3つの異なるオフセット(UTC + 0、UTC + 1、およびUTC + 2)を通過したためです。
アプリケーションが上記のいずれかのシナリオに大きく依存している場合は、Win32 APIではなく、IANAデータソースでAPIを使用することをお勧めします。
毎年明らかに10か月の第3週に定期的に発生するDSTの開始日に、第2週に値が設定されている理由はありますか?
はい、上記のとおり、1msの意図的なエラーが原因です。 2017年の夏時間は、ブラジルの夏時間がある地域では、10月15日日曜日の00:00:00.000に始まります。それは月の第3日曜日です。 1ミリ秒前は、10月14日土曜日の23:59:59.999で、これは秒土曜日です。これは毎年異なる可能性があるため、動的DSTデータがあります。
Windowsレジストリに書き込まれたタイムゾーンは信頼できますか?信頼できない場合、Windows APIのどの機能を使用して、ローカルマシンで設定されたタイムゾーンとは異なるタイムゾーンで書き込まれた日付からDSTでタイムゾーンを変換する必要がありますか?
Win32 APIを使用している場合、それらはレジストリデータ自体を使用するため、レジストリデータを直接操作する必要はありません。 APIの「動的」バージョンは、Dynamic DSTデータの前年比の変化を適切に考慮しているため、優先する必要があります。これらは「Ex」というラベルが付いている場合があります。たとえば、質問した関数は TzSpecificLocalTimeToSystemTimeEx
関数で処理するのが最適です。
...
そうは言っても、アプリケーションでWindowsタイムゾーンデータの使用を回避できる場合は、そうすることをお勧めします。 IANAデータソース、またはそれらから派生したデータソースを優先します。 IANAタイムゾーンデータを操作する方法はたくさんあります。 WinRT/UWPのWindows.Globalization.Calendar
やWindows.Globalization.DatetimeFormatting.DateTimeFormatter
などの新しいWindows APIは実際に IANAタイムゾーン を使用しますが、それは明らかに将来への道のりです。標準のC++スペースでは、 ハワードヒナンの日付/ tzライブラリ 、または ICUプロジェクト によって提供されるものを使用することを強くお勧めします。他にもいくつかの実行可能な選択肢があります。
Mattの投稿で詳細レベルを確認できるのは素晴らしいことです。
「いくつかのタイムゾーン、特に「E.南アメリカ標準時「1つ」
MattのWindowsタイムゾーンデータへの非常に詳細かつ徹底的な貢献に加えて、他に概説されているさまざまな機関、NGO、政府機関によるかなりの調査があることを除けば、これ以上追加するものはありません。例として、モロッコのような場所では、年に4回移行するだけでなく、政府がこの地域でDSTの公式の遵守を設定し、場合によっては わずかなリードタイム で、追加の公開と展開の課題につながります。 (政府が 決定を複数回修正するときは言うまでもありません )。
したがって、重要な依存関係がある一部のアプリケーションでは、IANAソースへのAPIが優先されるか、Windows.Globalizationでタイムゾーンデータを呼び出すことが推奨されます。
北半球でもフォールバックする直前に、しゃれを許してくれるなら、これはすべてタイムリーです。