如何获取 UTC TimeZone DisplayName .NET 4.0?
How to get UTC TimeZone DisplayName .NET 4.0?
我用时区 DisplayName 设置了一个 winforms 组合框:
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
returnsUTC
。这是不寻常的,因为上面的枚举显示不同的 DisplayName。
TimeZoneInfo.FindSystemTimeZoneById("UTC")
也 returns "UTC"。
TimeZoneInfo.FindSystemTimeZoneById("(UTC) Co-ordinated Universal Time")
和 TimeZoneInfo.FindSystemTimeZoneById("Co-ordinated Universal Time")
不起作用。
如何获取枚举中显示对应的本地化字符串(UTC) Co-ordinated Universal Time
?
我能想到的唯一解决方案是存储字符串 "(UTC) Co-ordinated Universal Time"
,但我担心上面的列表可能会在不同的本地化中发生变化。
嗯,我通过打印时区的 Id 找到了答案。
所需字符串打印为:
TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time"); // Wrong
编辑:
正如 Matt Johnson 指出的那样,上面的代码显示了伦敦时区。
这是另一个尝试:
TimeZoneInfo.GetSystemTimeZones().First(t=>t.Id=="UTC").DisplayName
几件事:
DisplayName
不是ID。只有 Id
属性 返回的值才适合与 FindSystemTimeZoneById
方法一起使用。
对于您的下拉列表,您应该显示 DisplayName
,但您应该 store 仅 Id
.
DisplayName
、StandardName
和 DaylightName
属性由操作系统 本地化 ,而不是全球化.NET Framework 的功能。
ID 将始终为英文。他们永远不会因本地化而改变。
您应该永远不要向最终用户显示 ID 或以任何特定方式解释它们。使用了许多不同的相互冲突的约定,有些只是编造的。有关示例,请参阅 the timezone tag 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_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\UTC";
string s = Registry.GetValue(key, "Display", null) as string;
再次提醒,时区显示名称的所有本地化都是由操作系统完成的。因此,这种方法适用于 Windows 桌面应用程序,但对 Web 应用程序没有多大意义。此外,如果您的应用程序在内部支持多种语言,您将无法依赖 .NET 全球化来获得任何时区显示名称。在这种情况下,您将需要提供自己的显示名称来源,可能在 .resx 文件中,或者您可以考虑使用我的 TimeZoneNames 库。
我用时区 DisplayName 设置了一个 winforms 组合框:
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
returnsUTC
。这是不寻常的,因为上面的枚举显示不同的 DisplayName。
TimeZoneInfo.FindSystemTimeZoneById("UTC")
也 returns "UTC"。
TimeZoneInfo.FindSystemTimeZoneById("(UTC) Co-ordinated Universal Time")
和 TimeZoneInfo.FindSystemTimeZoneById("Co-ordinated Universal Time")
不起作用。
如何获取枚举中显示对应的本地化字符串(UTC) Co-ordinated Universal Time
?
我能想到的唯一解决方案是存储字符串 "(UTC) Co-ordinated Universal Time"
,但我担心上面的列表可能会在不同的本地化中发生变化。
嗯,我通过打印时区的 Id 找到了答案。
所需字符串打印为:
TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time"); // Wrong
编辑: 正如 Matt Johnson 指出的那样,上面的代码显示了伦敦时区。
这是另一个尝试:
TimeZoneInfo.GetSystemTimeZones().First(t=>t.Id=="UTC").DisplayName
几件事:
DisplayName
不是ID。只有Id
属性 返回的值才适合与FindSystemTimeZoneById
方法一起使用。对于您的下拉列表,您应该显示
DisplayName
,但您应该 store 仅Id
.DisplayName
、StandardName
和DaylightName
属性由操作系统 本地化 ,而不是全球化.NET Framework 的功能。ID 将始终为英文。他们永远不会因本地化而改变。
您应该永远不要向最终用户显示 ID 或以任何特定方式解释它们。使用了许多不同的相互冲突的约定,有些只是编造的。有关示例,请参阅 the timezone tag 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_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\UTC"; string s = Registry.GetValue(key, "Display", null) as string;
再次提醒,时区显示名称的所有本地化都是由操作系统完成的。因此,这种方法适用于 Windows 桌面应用程序,但对 Web 应用程序没有多大意义。此外,如果您的应用程序在内部支持多种语言,您将无法依赖 .NET 全球化来获得任何时区显示名称。在这种情况下,您将需要提供自己的显示名称来源,可能在 .resx 文件中,或者您可以考虑使用我的 TimeZoneNames 库。