获取一个国家/地区的默认时区(通过CultureInfo)

是否有为每个国家/地区提供默认时区的计划或表格?

是的,美国,加拿大和俄罗斯有多个时区。 (我认为每个其他国家只有一个。)但如果一个国家知道而不是仅仅提供从格林威治标准时间开始的清单,那么最好开始。

最好是在C#中,但我会把它带入任何东西并转换为C#。

正如问题评论中所指出的那样,您无法为每个国家/地区获得单个时区。 有多个时区的国家的情况太多了。

可以做的是将标准IANA / Olson时区列表过滤到特定国家/地区的可用时间列表。

在C#中执行此操作的一种方法是使用Noda Time :

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

传递两位数的ISO-3166国家代码,例如澳大利亚的"AU" 。 结果是:

 "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 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补充数据 。 它没有比那更接近“官方”。

可能不是你想要的,但试试这个: http : //msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx

要获得特定时区:

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

要查看可用区域:

 ReadOnlyCollection zones = TimeZoneInfo.GetSystemTimeZones(); foreach (TimeZoneInfo zone in zones) { Console.WriteLine(zone.Id); } 

为了获得CountryCode – > TimeZoneInfo映射,我使用了来自Matt(第二个代码片段)的答案,但它在许多情况下都不起作用。 找到更简单,更可靠的解决方案(使用相同的Noda Time):TzdbDateTimeZoneSource.Default.WindowsMapping.MapZones基本上拥有所有数据。

代码示例:

 Dictionary 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 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; } 

最新的Windows版本包含文件%WINDIR%\Globalization\Time Zone\timezoneMapping.xml ,它将Olson映射到Windows时区,您可以将其作为常规XML进行查询。 我不知道,但也许C#已经有了一个适合它的类。