以不同语言获取系统时区
我目前正在获取所有时区列表,如下所示:
var TheListOfAllTimezones = TimeZoneInfo.GetSystemTimeZones();
例如,巴黎的时区具有W. Europe Standard Time
的DisplayName
属性。 现在我如何用另一种语言获取此列表? 例如,对于法国的用户,我想展示Heure Europe de l'Ouest
。
谢谢。
更改CurrentCulture
不起作用,因为信息来自注册表(XP)或多语言用户界面(MUI)DLL(Vista,Windows 7)。
在Vista或Windows 7上,您可以安装其他语言并更改显示语言( 区域和语言 – > 键盘和语言 – > 显示语言 )。 需要重新启动。 这个,只有这个,实际上会改变TimeZoneInfo
使用的语言。
在Windows 7上,只有Ultimate和Enterprise允许安装其他语言 – 通过安装多语言用户界面包 。
安装其他语言后,您应该能够在system32文件夹中找到DLL(查找tzres
),并可能使用Visual Studio导出资源。
至于可信/官方消息来源 – 关于BCL团队msdn的文章怎么样:
…当MUI支持不可用时,显示字符串可以从多语言用户界面(MUI)DLL ,tzres.dll或直接从注册表加载。 支持MUI的操作系统(如Windows Vista)包含
MUI_Display
,MUI_Std
和MUI_Dlt
键,这些键由操作系统区域设置间接控制。 在Windows XP和Windows Server 2003等低级平台上,仅存在Display
,Std
和Dlt
键。Display
,Std
和Dlt
键值仅以操作系统的默认语言进行本地化。
那么他们写的关于CurrentUICulture
什么?
由于Windows时区注册表体系结构, CurrentUICulture设置不会影响这些TimeZoneInfo属性的值 。
从文档 :
此方法返回的集合使用当前区域性按显示名称排序。
在获取列表之前,您是否尝试将当前文化更改为用户的文化?
那可能行不通。 可用的唯一显示名称可能是已安装的Windows版本。 也就是说,如果你有一个美国英语版本的Windows,法语显示名称可能不在那里。 查看我的注册表( HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Time Zones
),我只看到英文名称。
如果您的线程的CurrentCulture
是法语(“fr-FR”),并且如果该语言是Windows版本的“本机”,那么属性StandardName
和DaylightName
将使用法语。
编辑:
它看起来不像改变线程的CurrentCulture
会有所帮助。 时区都来自注册表(参见Jim Mischel对路径的回答),看起来Windows安装的语言决定了这些值。 ID(注册表路径中的键)始终为英语,而其他属性则取决于Windows语言。
您输出以下代码的内容是什么:
Console.WriteLine(CultureInfo.InstalledUICulture.DisplayName); var tzi = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time"); Console.WriteLine(tzi.Id); // always English Console.WriteLine(tzi.DisplayName); // localized Console.WriteLine(tzi.StandardName); // localized Console.WriteLine(tzi.DaylightName); // localized
如何创建像“TimeZoneInfoExtension”这样的类,它将具有名为ToLocolizedString的静态方法:
public static class TimeZoneInfoExtensions { public static string ToLocalizedString(this TimeZoneInfo timeZone) { switch (timeZone.Id) { case "Dateline Standard Time": return i18n.DatelineStandardTime; case "UTC-11": return i18n.UTC11; case "Hawaiian Standard Time": return i18n.HawaiianStandardTime; case "Alaskan Standard Time": return i18n.AlaskanStandardTime; .... default: throw new NotImplementedException(); } } }
i18n是一个有资源的class级。 是的,你必须手动填写翻译。 但我只是在不同的系统语言中使用这样的东西来生成翻译:
Regex rgx = new Regex("[ +-]"); foreach (var timeZone in TimeZoneInfo.GetSystemTimeZones()) { Console.WriteLine(" ", rgx.Replace(timeZone.Id, string.Empty)); Console.WriteLine(" {0} ", timeZone.DisplayName); Console.WriteLine(" "); }
然后你可以根据你的CurrentCulture使用它,如下所示:
foreach (var timeZoneInfo in TimeZoneInfo.GetSystemTimeZones()) { Console.WriteLine(timeZoneInfo.ToLocalizedString()); }