WindowsとIANAのタイムゾーンを変換する方法


149

タイムゾーンタグwikiで説明されているように、タイムゾーンには2つの異なるスタイルがあります。

  • Windowsおよび.Net TimeZoneInfoクラス(Windowsで実行されている場合)で使用するためにMicrosoftが提供するものは、などの値で識別され"Eastern Standard Time"ます。

  • IANAがTZDBで提供しTimeZoneInfo、LinuxまたはOSXでの実行時に.NET クラスで使用されるものは、などの値で識別され"America/New_York"ます。

多くのインターネットベースのAPIはIANAタイムゾーンを使用しますが、多くの理由により、これをWindowsタイムゾーンIDに、またはその逆に変換する必要がある場合があります。

これはどのように.Netで実現できますか?

回答:


198

WindowsとIANAのタイムゾーン識別子間の変換用のデータの主なソースは、Unicode CLDRプロジェクトのwindowsZones.xml一部として配布されるファイルです。最新の開発バージョンはこちらから入手できます

ただし、CLDRは毎年2回だけリリースされます。これは、Windows更新の定期的な周期、およびIANAタイムゾーンデータベースの不定期な更新と相まって、CLDRデータを直接使用するだけでは複雑になります。タイムゾーンの変更自体は、世界のさまざまな政府の気まぐれで行われ、すべての変更がそれぞれの発効日の前にこれらのリリースサイクルに入るように十分に注意して行われるわけではないことに注意してください。

CLDRで厳密にカバーされていない、処理が必要なエッジケースが他にもいくつかあり、新しいケースが時々ポップアップします。そのため、ソリューションの複雑さを、NugetからインストールできるTimeZoneConverterマイクロライブラリにカプセル化しました。

このライブラリの使用は簡単です。次に変換の例をいくつか示します。

string tz = TZConvert.IanaToWindows("America/New_York");
// Result:  "Eastern Standard Time"

string tz = TZConvert.WindowsToIana("Eastern Standard Time");
// result:  "America/New_York"

string tz = TZConvert.WindowsToIana("Eastern Standard Time", "CA");
// result:  "America/Toronto"

プロジェクトサイトには他にも例があります

IANAタイムゾーンは単一のWindowsタイムゾーンにマップできますが、その逆は当てはまらないことを認識することが重要です。1つのWindowsタイムゾーンが複数のIANAタイムゾーンにマップされる場合があります。これは、とのEastern Standard Time両方America/New_Yorkにマッピングされている上記の例で確認できますAmerica/Toronto。TimeZoneConverterは"001"、特に国コードを提供し、その国の別のゾーンに一致するものがない限り、「ゴールデンゾーン」と呼ばれる、CLDRでマークされたものを配信します。

注:この回答は長年にわたって進化してきたため、以下のコメントは現在のリビジョンに適用される場合と適用されない場合があります。詳細については、編集履歴を確認してください。ありがとう。


1
変換時にこのメソッドを使用すると(GMT+05:30) Chennai, Kolkata, Mumbai, New DelhiAsia/Calcuttaそれが必要になりますAsia/KolkataTzdbDateTimeZoneSource古い値が含まれているようです。
Anto Subash 2014年

1
@MattJohnsonは、Asia/Kolkatausing IanaToWindows メソッドの変換中に失敗します。それはで動作しAsia/Calcuttaている古いname.youは、メソッドを更新しましたですWindowsToIanaが、IanaToWindowsまた同じ問題を抱えています。機能していない他のいくつかのゾーンがありますAmerica/Argentina/Buenos_AiresAmerica/Indiana/IndianapolisAsia/Kathmandu
Anto Subash 2014年

1
@AntoJSubash-繰り返しになりますが、素晴らしい観察です!IanaToWindows補正する方法を編集しました。どうもありがとう!
Matt Johnson-Pint 2014年

2
@MattJohnson @sirroccoの2番目の観察です。正規IDを使用することもvar canonical = tzdbSource.CanonicalIdMap[ ianaZoneId ]; links = Enumerable.Repeat( canonical, 1 ).Concat( links );、私にとってはトリックのようでした。
ヨハネスルドルフ

2
@sirrocco-すみません、もっと早くコメントが表示されませんでした。機能を更新しました。ありがとう!
Matt Johnson-Pint 2015年

4

これは古い質問であることはわかっていますが、ここで共有するユースケースがありました。これは、検索時に見つけた最も関連性の高い投稿だからです。私は、ドッカーLinuxコンテナーを使用して.NET Coreアプリを開発していましたが、Windowsサーバーへの展開用でした。したがって、Windowsタイムゾーン名をサポートするために必要なのは、Docker Linuxコンテナーだけでした。次のようにして、アプリケーションコードを変更せずにこれを機能させました。

cp /usr/share/zoneinfo/America/Chicago "/usr/share/zoneinfo/Central Standard Time"
cp /usr/share/zoneinfo/America/New_York "/usr/share/zoneinfo/Eastern Standard Time"
cp /usr/share/zoneinfo/America/Denver "/usr/share/zoneinfo/Mountain Standard Time"
cp /usr/share/zoneinfo/America/Los_Angeles "/usr/share/zoneinfo/Pacific Standard Time"

次に、私の.NETコードでは、以下は変更なしで機能しました。 TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")


1
これは、すぐに使える優れた考え方です。いくつかの特定のタイムゾーンをカバーしている限り、これは問題ないようです。米国には4つ以上あることに注意してください。現在の日中50州をカバーするために、あなたはまたのためにリンクを追加する必要がありますAmerica/Phoenix"US Mountain Standard Time"Pacific/Honolulu"Hawaiian Standard Time"America/Anchorage"Alaskan Standard Time"、とAmerica/Adak"Aleutian Standard Time"。それは米国の領土や歴史的な矛盾をカバーしていませんが、あなたを始めるでしょう。
Matt Johnson-Pint

2
全世界を対象とする場合や、有効なタイムゾーン識別子を処理する場合は、この方法はお勧めしません。リストは長すぎ、揮発性が高すぎます。
Matt Johnson-Pint
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.