正如问题的 cmets 中所确定的,您无法为每个国家/地区获得一个时区。拥有多个时区的国家/地区的例子太多了。
您可以做的是将标准IANA/Olson time zones 列表过滤到特定国家/地区可用的列表。
在 C# 中执行此操作的一种方法是使用 Noda Time:
IEnumerable<string> 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"
如果出于某种原因您希望 Windows 时区标识符可以与 TimeZoneInfo 对象一起使用,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 的映射是 IANA 时区数据库本身的一部分,位于 zone.tab 文件中。 IANA 到 Windows 的映射数据来自Unicode CLDR supplemental data。没有比这更接近“官方”的了。