我用时区设置了一个winforms组合框DisplayName:
var zoneList = TimeZoneInfo
.GetSystemTimeZones()
.Where(z => z.BaseUtcOffset.Minutes == 0)
.Select(z => z.DisplayName);
显示如下列表:
...
(UTC-01:00) Azores
(UTC-01:00) Cabo Verde Is.
(UTC) Casablanca
(UTC) Co-ordinated Universal Time
(UTC) Dublin, Edinburgh, Lisbon, London
(UTC) Monrovia, Reykjavik
(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna
...
我想将默认项发送给(UTC) Co-ordinated Universal Time
。但是,TimeZoneInfo.Utc.DisplayName
返回UTC
。这是不寻常的,因为上面的枚举显示不同的DisplayName。
TimeZoneInfo.FindSystemTimeZoneById("UTC")
也返回"UTC"。TimeZoneInfo.FindSystemTimeZoneById("(UTC) Co-ordinated Universal Time")
和TimeZoneInfo.FindSystemTimeZoneById("Co-ordinated Universal Time")
不能工作
如何获得对应于在枚举(UTC) Co-ordinated Universal Time
中显示的本地化字符串?
我能想出的唯一解决方案是存储字符串"(UTC) Co-ordinated Universal Time"
,但我担心上面的列表可能会在不同的本地化中发生变化。
几点:
-
DisplayName
不是ID。只有Id
属性返回的值才适合与FindSystemTimeZoneById
方法一起使用。 -
对于你的下拉列表,你应该显示
DisplayName
,但是你应该只存储Id
。 -
DisplayName
,StandardName
和DaylightName
属性由操作系统本地化,而不是由。net框架的全球化特性。 -
id 总是为英文。它们不会因为本地化而改变。
-
您应该永远不要向最终用户显示id或以任何特定的方式解释它们。有许多不同的相互冲突的惯例被使用,有些只是编造出来的。请参阅时区标签wiki中的Windows时区部分,以获取一些示例。
-
"Coordinated"是一个没有连字符的单词。这些在Windows中是正确的,所以我认为你一定是自己添加了连字符。
-
确认显示名称中显示的偏移量只是基本偏移量。它们并不指示时区是否调整为夏令时。当夏令时生效时,此列表中的偏移量也不会改变。
-
你是正确的
TimeZoneInfo.Utc.DisplayName == "UTC"
,TimeZoneInfo.FindSystemTimeZoneById("UTC").DisplayName
也是如此。但是,TimeZoneInfo.GetSystemTimeZones()
返回的UTC条目具有显示名称的完整形式:"(UTC) Coordinated Universal Time"
。因此,如果您通过枚举TimeZoneInfo.GetSystemTimeZones()
的结果来显示下拉列表,那么您可以直接使用结果。但是如果你想直接得到那个显示名,你必须这样做:
string s = TimeZoneInfo.GetSystemTimeZones().First(x => x.Id == "UTC").DisplayName;
,或者:
string key = @"HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionTime ZonesUTC"; string s = Registry.GetValue(key, "Display", null) as string;
同样,请记住时区显示名称的所有本地化都是由操作系统完成的。因此,这种方法适用于Windows桌面应用程序,但不适用于web应用程序。此外,如果您的应用程序在内部支持多种语言,那么您将无法依赖. net全球化来处理任何时区显示名称。在这种情况下,您需要提供自己的显示名称源,可能在.resx文件中,或者您可以使用我的TimeZoneNames库。
嗯,我通过打印时区Id找到了答案。
所需字符串打印为:
TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time"); // Wrong
编辑:正如Matt Johnson所指出的,上面的代码显示了伦敦时区。
再试一次:
TimeZoneInfo.GetSystemTimeZones().First(t=>t.Id=="UTC").DisplayName