我有一个全球网站,它将IANA时区ID传递给服务器,并使用Noda Time映射到c#5 web应用中的Windows时区。
"其他/ UTC"正在传递给服务器,但Noda Time无法将其映射到Windows时区。如何映射IANA时区ID?
public TimeZoneInfo GetTimeZoneByIanaId(string ianaTimeZoneId)
{
TzdbDateTimeZoneSource timeZoneSource = TzdbDateTimeZoneSource.Default;
IList<MapZone> zoneMaps = timeZoneSource.WindowsMapping.MapZones;
// resolve any link, since the CLDR doesn't necessarily use canonical IDs
IList<string> mapZoneIds = timeZoneSource.CanonicalIdMap.Where(map => map.Value.Equals(ianaTimeZoneId, StringComparison.OrdinalIgnoreCase)).Select(x => x.Key).ToList();
MapZone mapZone = zoneMaps.FirstOrDefault(zoneMap => zoneMap.TzdbIds.Any(mapZoneIds.Contains));
if (mapZone == null)
{
throw new TimeZoneNotFoundException("Unable to determine the clients timezone using the jsTimezoneDetect plugin");
}
TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById(mapZone.WindowsId);
if (timeZone == null)
{
throw new TimeZoneNotFoundException("Unable to determine the clients timezone from NodaTime");
}
return timeZone;
}
答案 0 :(得分:7)
正如Jon指出的那样,"Etc/UTC"
没有CLDR映射。相反,CLDR会将Windows "UTC"
时区映射到"Etc/GMT"
。恕我直言 - 这是错误的。
CLDR需要&#34;稳定标识符&#34;,因此在时区名称更改时,传统上不会更新其映射。相反,人们通常会遵循&#34;链接&#34;在时区数据库中映射到规范区域。
但是 - TZDB并不认为"Etc/GMT"
是"Etc/UTC"
的链接。它们是两个不同的区域。还有"Etc/UCT"
。这样,依赖于TZDB时区缩写的应用程序可以使用它们选择的缩写(GMT,UTC或UCT)。 (See discussion here.)
无论如何 - 感谢您提醒我们这个问题。我更新了mapping functions以考虑到这一点。