C# 获取不同语言的系统时区

C# 获取不同语言的系统时区,c#,asp.net,timezone,C#,Asp.net,Timezone,我目前得到的所有时区列表如下: var TheListOfAllTimezones = TimeZoneInfo.GetSystemTimeZones(); 例如,巴黎的时区有一个DisplayName属性,即W.欧洲标准时间。现在我如何用另一种语言获取此列表?例如,对于法国的用户,我想显示Heure Europe de l'Ouest 谢谢 来自: 此方法返回的集合使用按显示名称排序 当前的文化 在获取列表之前,您是否尝试过将当前区域性更改为用户的区域性 这可能行不通。唯一可用的显示名称可能

我目前得到的所有时区列表如下:

var TheListOfAllTimezones = TimeZoneInfo.GetSystemTimeZones();
例如,巴黎的时区有一个
DisplayName
属性,即
W.欧洲标准时间
。现在我如何用另一种语言获取此列表?例如,对于法国的用户,我想显示
Heure Europe de l'Ouest

谢谢

来自:

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

在获取列表之前,您是否尝试过将当前区域性更改为用户的区域性


这可能行不通。唯一可用的显示名称可能是已安装的Windows版本的名称。也就是说,如果您有一个美英版本的Windows,法语显示名称可能不存在。查看我的注册表(
HKEY\U LOCAL\U 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

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

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

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

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

关于可信/官方来源,如何:

…显示字符串从多语言用户加载 接口(MUI)DLL、tzres.DLL,或直接从注册表获取 MUI支持不可用。支持MUI的操作系统,如 Windows Vista包含
MUI_显示
MUI_标准
MUI_Dlt
键,这些键 由操作系统区域设置间接控制。 在底层平台上,如Windows XP和Windows Server 2003, 只有
显示
Std
Dlt
键存在显示<代码>和<代码>标准<代码>和<代码>Dlt<代码> 键值仅以操作系统的默认语言本地化 系统。

那么他们写了些什么关于当前的UICulture呢

由于Windows时区注册表体系结构, CurrentUICulture设置不会影响这些值 时区信息属性


如何创建一些类,如“TimeZoneInfoExtension”,它将具有名为ToLoClizedString的静态方法:

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>");
}

有趣。我这里有丹麦版本的Windows,我在注册表中看到了丹麦文的
Std
Dlt
。在
.NET
对象中,我看到了英语中的
Id
属性,以及丹麦语中的
StandardName
DaylightName
属性。我的操作系统是英文的,应用程序将托管在Azure上,所以我想也会是英文的。@JonSkeet好的,看起来它只取决于操作系统语言。我正在一台丹麦语的Windows机器上尝试这个。例如,我的
Id
等于
“浪漫标准时间”
;而
DisplayName
”(UTC+01:00)科本哈文,斯德哥尔摩,奥斯陆,马德里,巴黎“
;而
StandardName
“Rom,normaltid”
;DaylightName是
“Rom,sommertid”
。是的,真的很奇怪,没有内置的方法来获取不同语言的列表。@JonSkeet:知道怎么做吗?@frenchie:不幸的是没有:(通常的方法是给出一个城市列表而不是时区名称-Unicode CLDR给出了要列出的城市示例,但这些城市是TZDB时区的…@JeppeStigNielsen:是的,我认为CLDR对不同语言的城市有不同的名称。我必须检查一下。它确实提出了一个问题,即为什么DisplayName属性是不同的。)是如此糟糕的记录…我真的不知道,但除非你用不同的语言设置创建自己的虚拟机,否则我的赌注是英语。要更好地理解这个问题,请阅读并查看解决方案。
foreach (var timeZoneInfo in TimeZoneInfo.GetSystemTimeZones())
{
    Console.WriteLine(timeZoneInfo.ToLocalizedString());
}