すべての国にデフォルトのタイムゾーンを提供するプログラムまたはテーブルはありますか?
はい、米国、カナダ、ロシアには複数のタイムゾーンがあります。(他のすべての国には 1 つしかないと思います。) ただし、GMT から始まるリストを提供するだけでなく、国がわかっている場合は、最も可能性の高い国から始める方がよいでしょう。
できればC#ですが、何でも取り入れてC#に変換します。
質問のコメントで特定されているように、国ごとに 1 つのタイム ゾーンを取得することはできません。複数のタイムゾーンを持つ国のケースが多すぎます。
できることは、標準のIANA/Olson タイム ゾーンのリストを特定の国で利用可能なものに絞り込むことです。
C# でこれを行う 1 つの方法は、Noda Timeを使用することです。
IEnumerable<string> zoneIds = TzdbDateTimeZoneSource.Default.ZoneLocations
.Where(x => x.CountryCode == countryCode)
.Select(x => x.ZoneId);
"AU"
オーストラリアなど、2 桁の ISO-3166 国コードを渡します。結果は次のとおりです。
"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"
また、なんらかの理由で、TimeZoneInfo
オブジェクトで使用できる Windows タイム ゾーン識別子が必要な場合、Noda Time はそれらもマップできます。
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 へのマッピングは、zone.tabファイル内の IANA タイム ゾーン データベース自体の一部です。IANA から Windows へのマッピング データは、Unicode CLDR 補足データから取得されます。それ以上に「公式」に近づくことはありません。
あなたが探しているものではないかもしれませんが、これを試してください: http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx
特定のタイムゾーンを取得するには:
TimeZoneInfo tZone = TimeZoneInfo.FindSystemTimeZoneById("E. Australia Standard Time");
利用可能なゾーンを表示するには:
ReadOnlyCollection<TimeZoneInfo> zones = TimeZoneInfo.GetSystemTimeZones();
foreach (TimeZoneInfo zone in zones)
{
Console.WriteLine(zone.Id);
}
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;
}