9

ここでの私の要件はかなり標準的です。ユーザーが現在の TimeZone を選択して、アカウントに対して保存できるようにする必要があります。DateTime次に、この値を使用して、格納された値をローカライズされた時間に変換します。

私の現在の考えは、ユーザーがTimeZoneInfo.Idリストから .NET を選択できるようにすることです (よりわかりやすい説明を可能にするために DB に保持されますが、を使用して構築されますTimeZoneInfo.GetSystemTimeZones())。次に、この値を使用して関連するTimeZoneInfoインスタンスを返しTimeZoneInfo.FindSystemTimeZoneById()、変換を実行します。ここで私が目にする主な問題はTimeZoneInfo.Id、レジストリに保持されている値であり、「標準」ID ではないことです (たとえば、Olson と比較して)。そのため、サーバーの更新/移行により、保存された ID が完全に無効になり、変換が中断される可能性があります。

要するに、このアプローチは有効/安全ですか? そうでない場合、ユーザーのタイムゾーン設定を保存しながら、追加のロジックなしで夏時間などを処理するより良い方法はありますか?

4

1 に答える 1

9

この古い未回答の質問を見つけたので、それを突き刺すべきだと思いました。

要するに、このアプローチは有効/安全ですか?

それはすべて、あなたがそれらをどうするかによって異なります。

サーバー側のコードでのみ使用している場合は、はい。Idタイムゾーンの を保存し、対応する をユーザーに表示するだけDisplayNameです。 FindSystemTimeZoneByIdこれにGetSystemTimeZonesは完全に有効です。

Id値は常に同じDisplayNameですが、コードを実行している Windows オペレーティング システムの言語によってプロパティが異なることに注意してください。実装はカルチャに対応していないため、.Net で別のターゲット カルチャを設定するだけでは、DisplayName文字列は変更されません。

Microsoft Windows タイム ゾーン データベースのレコードはかなり安定しており、Windows Update によって更新されています。 一部の情報はレジストリから取得されますが、ローカライズされたリソース文字列はtzres.dll. もちろん、そのすべてはTimeZoneInfo関連するクラスによって隠されています。

ただし、これらのタイムゾーンの値を他のシステムに渡す場合はId注意してください。以前のバージョンの Windows にはいくつかのバリエーションがあります。たとえば、以前はすべての表示名に「GMT」と表示されていましたが、現在はより正確に「UTC」と表示されていることがわかっています。値は同じですが、Id他に何が一貫していないかを誰が正確に知っていますか。特に、ターゲット コンピューターが、所有しているのと同じ一連の Windows Update を受信して​​いない場合。ところで、アップデートはここで発表されます。

また、Windows タイム ゾーン データベースについていくつか知っておく必要があります。

  • 1 暦年あたり 2 回を超える DST 移行を表すことはできません。たとえば、2010 年、エジプトのカイロでは4 回の移行が行われました。Microsoft は修正プログラムを発行しましたが、これは妥協的な修正を行っただけで、歴史的に正確なものではありませんでした。このような歴史的な変化があり、適切に表すことができない他のゾーンがあります。

  • Windows XP/2003 と Vista/2008 の間でいくつかの変更がありました。ここには、レジストリの使用方法に関する多くの詳細とともに、これに関するいくつかの非常に優れた情報があります。

  • Microsoft は、独自のタイム ゾーン データベースを持つ唯一の大手企業です。その他の地域では、IANA/Olson データベースが使用されています。これは、相互運用性の問題につながります。timezone tag wikiにこれについてのまともな記事があります。

また、 はおよびクラスTimeZoneInfoと密接に関連していることも知っておく必要があります。これらには独自の癖があります。 やや使用可能ですが、ニュアンスがいっぱいです。読んだ:DateTimeDateTimeOffsetDateTimeOffsetDateTime

.Net での日付と時刻のはるかに優れた解決策は、 NodaTimeを使用することです。このライブラリは、CLDR マッピングを含む両方のタイム ゾーン データベースを実装します。また、トラブルに巻き込まれない、より安全な API も提供します。少し再学習する必要があるかもしれませんが、気が付く前にLocalDateTime、 、ZonedDateTimeOffsetDateTimeなどのクラスを使用することになりInstantます。

時間管理のルールは政治家に任せているため、タイム ゾーン データベースが頻繁に更新されるという問題がまだ残っています。しかし、TZDB関係者は、データベースを歴史的に正確に保ち、​​ゾーン名が変更されたときにエイリアス/リンクを提供するという非常に優れた仕事をしています。ここで tz 名のリストを確認できます。

また、NodaTime を使用する場合は、ディストリビューションにコンパイルされた TZDB のコピーをそのまま使用するか、独自のコピーをアプリケーションと共に出荷するかを選択できます。ホスト オペレーティング システムに依存することなく、(理論的には) 独自のコードを記述して IANA から最新バージョンを取得し、アプリケーションを最新の状態に保つことができます。

于 2013-05-21T21:42:32.517 に答える