如的时区标签维基,有两种不同风格的时区。
As described in the timezone tag wiki, there are two different styles of time zones.
对于那些使用Windows和.Net Those provided by Microsoft for use with Windows and the .Net 这些都是由一个值确定了TZDB提供IANA如 Those provided by IANA in the TZDB are identified by a value such as 很多基于互联网的API使用的IANA时区,但对于众多的原因之一,可能需要将其转换为Windows时区ID,反之亦然。 Many Internet-based APIs use the IANA time zones, but for numerous reasons one might need to convert this to a Windows time zone id, or vice-versa. 如何在.net中可能? How can this be accomplished in .Net? 有关Windows和IANA时区标识符之间的转换数据的主要来源是的单向code CLDR 。 The primary source of the data for conversion between Windows and IANA time zone identifiers is part of the Unicode CLDR. 在大多数情况下,一个IANA时区可以被映射到一个单一的视窗时区。但相反的是不正确的。一个单一的Windows时区可能映射到多个IANA时区。 In most cases, an IANA time zone can be mapped to a single Windows time zone. But the reverse is not true. A single Windows time zone might be mapped to more than one IANA time zone. 在除了作为一个卓越的日期和时间的API,在野田佳彦时间库包含了CLDR映射的嵌入式副本。 In addition to being a superior date time API, the Noda Time library contains an embedded copy of the CLDR mappings. 下面的功能可以被用来转换: The following functions can be used to convert: 请注意,该映射UTC已被另案处理。这是因为CLDR错误地映射UTC到 Note that the mapping for UTC has to be handled separately. This is because the CLDR erroneously maps UTC to 的TimeZoneInfo
类是由一个值来识别,如东部标准时间。
TimeZoneInfo
class are identified by a value such as Eastern Standard Time
.
美国/纽约
。America/New_York
.推荐答案
// This will return the Windows zone that matches the IANA zone, if one exists.
public string IanaToWindows(string ianaZoneId)
{
var utcZones = new[] { "Etc/UTC", "Etc/UCT", "Etc/GMT" };
if (utcZones.Contains(ianaZoneId, StringComparer.Ordinal))
return "UTC";
var tzdbSource = NodaTime.TimeZones.TzdbDateTimeZoneSource.Default;
// resolve any link, since the CLDR doesn't necessarily use canonical IDs
var links = tzdbSource.CanonicalIdMap
.Where(x => x.Value.Equals(ianaZoneId, StringComparison.Ordinal))
.Select(x => x.Key);
// resolve canonical zones, and include original zone as well
var possibleZones = tzdbSource.CanonicalIdMap.ContainsKey(ianaZoneId)
? links.Concat(new[] {tzdbSource.CanonicalIdMap[ianaZoneId], ianaZoneId})
: links;
// map the windows zone
var mappings = tzdbSource.WindowsMapping.MapZones;
var item = mappings.FirstOrDefault(x => x.TzdbIds.Any(possibleZones.Contains));
if (item == null) return null;
return item.WindowsId;
}
// This will return the "primary" IANA zone that matches the given windows zone.
// If the primary zone is a link, it then resolves it to the canonical ID.
public string WindowsToIana(string windowsZoneId)
{
if (windowsZoneId.Equals("UTC", StringComparison.Ordinal))
return "Etc/UTC";
var tzdbSource = NodaTime.TimeZones.TzdbDateTimeZoneSource.Default;
var tzi = TimeZoneInfo.FindSystemTimeZoneById(windowsZoneId);
if (tzi == null) return null;
var tzid = tzdbSource.MapTimeZoneId(tzi);
if (tzid == null) return null;
return tzdbSource.CanonicalIdMap[tzid];
}
ETC / GMT
和ETC / GMT
未设置起来作为TZDB链接ETC / UTC
。 更多关于此这里。 "Etc/GMT"
, and "Etc/GMT"
is not set up as a link to "Etc/UTC"
in the tzdb. More on this here.