以不同语言获取系统时区

时间:2012-10-31 17:11:29

标签: c# asp.net timezone

我目前正在获取所有时区的列表:

var TheListOfAllTimezones = TimeZoneInfo.GetSystemTimeZones();

例如,巴黎的时区的DisplayName属性为W. Europe Standard Time。现在我如何用另一种语言获取此列表?例如,对于法国用户,我想显示Heure Europe de l'Ouest

感谢。

enter image description here

4 个答案:

答案 0 :(得分:6)

更改CurrentCulture不起作用,因为信息来自注册表(XP)或多语言用户界面(MUI)DLL(Vista,Windows 7)。

在Vista或Windows 7上,您可以安装其他语言并更改显示语言(区域和语言 - > 键盘和语言 - > 显示语言)。需要重新启动。只有这样,才会实际更改TimeZoneInfo中使用的语言。

在Windows 7上,只有Ultimate和Enterprise允许安装其他语言 - 通过安装多语言用户界面包

安装其他语言后,您应该能够在 system32 文件夹中找到DLL(查找tzres),并可能使用Visual Studio导出资源。

关于可信/官方消息来源 - an article on msdn of the BCL Team怎么样:

  

...显示字符串是从多语言用户加载的   接口(MUI)DLL ,tzres.dll,或者直接来自注册表的时候   MUI支持不可用。支持MUI的操作系统,如   Windows Vista包含MUI_DisplayMUI_StdMUI_Dlt个密钥   由操作系统区域设置间接控制。   在Windows XP和Windows Server 2003等低级平台上,   仅存在DisplayStdDlt个键。 DisplayStdDlt   键值仅以操作的默认语言进行本地化   系统

那么他们写了什么CurrentUICulture

  

由于Windows时区注册表架构,    CurrentUICulture设置不会影响这些值   TimeZoneInfo属性

答案 1 :(得分:0)

来自the documentation

  

此方法返回的集合按显示名称使用排序   当前的文化。

在获取列表之前,您是否尝试将当前文化更改为用户的文化?

那可能行不通。可用的唯一显示名称可能是已安装的Windows版本。也就是说,如果你有一个美国英语版本的Windows,法语显示名称可能不在那里。查看我的注册表(HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Time Zones),我只看到英文名称。

答案 2 :(得分:0)

如果您的主题的CurrentCulture是法语(“fr-FR”),并且该语言与您的Windows版本是“原生”,那么属性StandardNameDaylightName看来会是法语。

修改

看起来好像改变线程的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

答案 3 :(得分:0)

如何创建类似" 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是一个有资源的类。是的,你必须手动填写翻译。但我只是在不同的系统语言中使用这样的东西来生成翻译:

Regex rgx = new Regex("[ +-]");
foreach (var timeZone in TimeZoneInfo.GetSystemTimeZones())
{
    Console.WriteLine("  <data name=\"{0}\" xml:space=\"preserve\">", rgx.Replace(timeZone.Id, string.Empty));
    Console.WriteLine("    <value>{0}</value>", timeZone.DisplayName);
    Console.WriteLine("  </data>");
}

然后您可以根据您的CurrentCulture使用它,如下所示:

foreach (var timeZoneInfo in TimeZoneInfo.GetSystemTimeZones())
{
    Console.WriteLine(timeZoneInfo.ToLocalizedString());
}