2013-10-30 5 views
11

各国のデフォルトタイムゾーンを提供するプログラムまたはテーブルはありますか?国のデフォルトタイムゾーンを取得する(CultureInfo経由)

はい、米国、カナダ、&ロシアには複数のタイムゾーンがあります。 (私は他の国は1つしかないと思う)しかし、GMTからのリストを提供するのではなく、国が分かっていれば最も可能性の高いものから始める方がよい。

好ましくはC#では、私は何かを取り込み、C#に変換します。

+2

中国。インド。イラン。ブラジル.... –

+0

「デフォルトのタイムゾーン」とは???国の首都にあるゾーン? – elgonzo

+1

オーストラリアには少なくとも3つのタイムゾーンがあり、一部の州には夏時間がありますが、少なくとも2つのタイムゾーンを使用する米国のインディアナもあります。 –

答えて

17

質問のコメントで確認されているように、各国の単一のタイムゾーンを取得することはできません。複数のタイムゾーンを持つ国はあまりにも多くの場合があります。

あなたはになります。は、標準IANA/Olson time zonesのリストを特定の国で利用可能なものに絞り込みます。 C#でこれを行うには

一つの方法は、Noda Timeである:

IEnumerable<string> zoneIds = TzdbDateTimeZoneSource.Default.ZoneLocations 
    .Where(x => x.CountryCode == countryCode) 
    .Select(x => x.ZoneId); 

は、オーストラリアのための"AU"として、2桁のISO-3166国コードを渡します。結果は以下のとおりです。何らかの理由であなたがTimeZoneInfoオブジェクトで使用できるWindowsのタイムゾーン識別子をたい場合

"Australia/Lord_Howe", 
"Australia/Hobart", 
"Australia/Currie", 
"Australia/Melbourne", 
"Australia/Sydney", 
"Australia/Broken_Hill", 
"Australia/Brisbane", 
"Australia/Lindeman", 
"Australia/Adelaide", 
"Australia/Darwin", 
"Australia/Perth", 
"Australia/Eucla" 

そして、野田時間があまりにもそれらをマッピングすることができます

var source = TzdbDateTimeZoneSource.Default; 
IEnumerable<string> windowsZoneIds = source.ZoneLocations 
    .Where(x => x.CountryCode == countryCode) 
    .Select(tz => source.WindowsMapping.MapZones 
     .FirstOrDefault(x => x.TzdbIds.Contains(
          source.CanonicalIdMap.First(y => y.Value == tz.ZoneId).Key))) 
    .Where(x => x != null) 
    .Select(x => x.WindowsId) 
    .Distinct() 

をもう一度、と呼ばれますオーストラリアのための"AU"を返します。

"Tasmania Standard Time", 
"AUS Eastern Standard Time", 
"Cen. Australia Standard Time", 
"E. Australia Standard Time", 
"AUS Central Standard Time", 
"W. Australia Standard Time" 

あなたは、このデータがどのように信頼性に疑問を抱いている場合は、マッピングをTZIDする国は、IANAタイムゾーンデータの一部でありますベース自体はzone.tabファイルにあります。 IANAからWindowsへのマッピングデータはUnicode CLDR supplemental dataから得られます。それはそれより "公式"には近くない。

+0

あなたは 'FO'国コードのために同じを試すことができますか? ( 'Faroi Islands')ファイル(' zone.tab')でコードを見つけることができますが、 'C#'ではこのコードの結果は得られません。 – Alex

+0

私が作成した編集を試してみてください。私はWindowsマッピングのIDが常にTZDB正準のものではないことを考慮に入れていませんでした。 –

2

は、あなたが探している正確に何であってもよいが、このしようとしないことがあります。使用可能なゾーンを表示するには

TimeZoneInfo tZone = TimeZoneInfo.FindSystemTimeZoneById("E. Australia Standard Time"); 

:特定のタイムゾーンを取得するにはhttp://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx

ReadOnlyCollection<TimeZoneInfo> zones = TimeZoneInfo.GetSystemTimeZones(); 

foreach (TimeZoneInfo zone in zones) 
{ 
    Console.WriteLine(zone.Id); 
} 
1

CountryCode - > TimeZoneInfoマッピングを取得するために、Matt(2番目のコードスニペット)の回答を使用しましたが、多くの場合は機能しませんでした。より簡単で信頼性の高いソリューションが見つかりました(同じNoda Timeを使用):TzdbDateTimeZoneSource.Default.WindowsMapping.MapZonesは基本的にすべてのデータを保持しています。

コードサンプル:

Dictionary<string, TimeZoneInfo> GetIsoToTimeZoneMapping() 
{ 
    var source = TzdbDateTimeZoneSource.Default; 

    return source.WindowsMapping.MapZones 
     .GroupBy(z => z.Territory) 
     .ToDictionary(grp => grp.Key, grp => GetTimeZone(source, grp)); 
} 

TimeZoneInfo GetTimeZone(TzdbDateTimeZoneSource source, IEnumerable<MapZone> territoryLocations) 
{ 
    var result = territoryLocations 
     .Select(l => l.WindowsId) 
     .Select(TimeZoneInfo.FindSystemTimeZoneById) 
     //pick timezone with the minimum offset 
     .Aggregate((tz1, tz2) => tz1.BaseUtcOffset < tz2.BaseUtcOffset ? tz1 : tz2); 

    return result; 
} 
関連する問題