Получение системных часовых поясов на разных языках
В настоящее время я получаю список всех часовых поясов вроде этого:
var TheListOfAllTimezones = TimeZoneInfo.GetSystemTimeZones();
Так, например, часовой пояс в Париже имеет свойство DisplayName
W. Europe Standard Time
. Теперь, как мне получить этот список на другом языке? Например, для пользователей во Франции я хотел бы отобразить Heure Europe de l'Ouest
.
Спасибо.
![enter image description here]()
Ответы
Ответ 1
Изменение CurrentCulture
не работает, поскольку информация поступает из реестра (XP) или из библиотеки многоязыкового интерфейса пользователя (MUI) (Vista, Windows 7).
В Vista или Windows 7 вы можете установить другие языки и изменить язык отображения (Регион и Язык → Клавиатуры и языки → Язык отображения). Требуется перезагрузка. Это, и только это, фактически изменит язык, используемый в TimeZoneInfo
.
В Windows 7 только Ultimate и Enterprise позволяют устанавливать другие языки - путем установки пакетов многоязыкового интерфейса пользователя.
После установки других языков вы сможете найти библиотеки DLL в папке system32 (найдите tzres
) и, возможно, экспортируйте ресурсы с помощью Visual Studio.
Что касается достоверных/официальных источников - как насчет статьи о msdn команды BCL:
... отображаемые строки загружаются либо из многоязычного пользователя Интерфейс (MUI) DLL, tzres.dll или прямо из реестра, когда Поддержка MUI недоступна. Операционные системы с поддержкой MUI, такие как Windows Vista содержит ключи MUI_Display
, MUI_Std
и MUI_Dlt
, которые косвенно контролируются региональными настройками операционной системы. На платформах нижнего уровня, таких как Windows XP и Windows Server 2003, существуют только ключи Display
, Std
и Dlt
. Display
, Std
и Dlt
ключевые значения локализуются только на языке по умолчанию для система.
Итак, что они пишут о CurrentUICulture
?
Из-за архитектуры реестра часовых поясов Windows, Настройки CurrentUICulture не влияют на значения этих Свойства TimeZoneInfo.
Ответ 2
Из документация:
Коллекция, возвращаемая этим методом, сортируется по отображаемому имени, используя текущая культура.
Вы пытались изменить текущую культуру в пользовательской культуре, прежде чем получать список?
Это может не сработать. Возможно, единственными отображаемыми именами являются те, которые установлены для установленной версии Windows. То есть, если у вас есть англо-английская версия Windows, французские отображаемые имена могут отсутствовать. Глядя на мой реестр (HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Time Zones
), я вижу только английские имена.
Ответ 3
Если CurrentCulture
вашего потока - французский ( "fr-FR" ), и если этот язык "родной" с вашей версией Windows, то свойства StandardName
и DaylightName
будут на французском языке, это кажется.
Edit:
Не похоже, что изменение CurrentCulture
потока поможет. Часовой пояс поступает из реестра (см. Ответ Джима Мишеля для пути), и похоже, что язык установки Windows определяет значения. Идентификаторы (которые являются ключами в пути реестра) всегда находятся на английском языке, а другие свойства зависят от языка 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
Ответ 4
Как создать класс, например "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());
}