Разница между CurrentCulture, InvariantCulture, CurrentUICulture и InstalledUICulture
В чем разница между CurrentCulture
, InvariantCulture
, CurrentUICulture
а также InstalledUICulture
от System.Globalization.CultureInfo
?
2 ответа
Я бы попытался дать более глубокий ответ, чем этот.
CurrentCulture следует использовать для форматирования. То есть числа, валюты, проценты, даты и время всегда должны быть отформатированы в соответствии с этой культурой, прежде чем их отобразить пользователю. Несколько примеров здесь:
const string CURRENCY_FORMAT = "c";
const string PERCENTAGE_FORMAT = "p";
DateTime now = DateTime.UtcNow; // all dates should be kept in UTC internally
// convert time to local and format appropriately for end user
dateLabel.Text = now.ToLocalTime().ToString(CultureInfo.CurrentCulture);
float someFloat = 12.3456f;
// yields 12,3456 for pl-PL Culture
floatLabel.Text = someFloat.ToString(CultureInfo.CurrentCulture);
// yields 12,35 zł for pl-PL Culture - rounding takes place!
currencyLabel.Text = someFloat.ToString(CURRENCY_FORMAT, CultureInfo.CurrentCulture);
// yields 1234,56% for pl-PL Culture - 1.0f is 100%
percentageLabel.Text = someFloat.ToString(PERCENTAGE_FORMAT, CultureInfo.CurrentCulture);
Важно отметить, что вы никогда не должны использовать float
ни double
для хранения информации, связанной с валютой, в первую очередь (decimal
это правильный выбор).
Другой общий случай использования CurrentCulture
анализ с учетом локали. Ваше приложение всегда должно позволять пользователям вводить данные в своем региональном формате:
float parsedFloat;
if (float.TryParse(inputBox.Text, NumberStyles.Float, CultureInfo.CurrentCulture, out parsedFloat))
{
MessageBox.Show(parsedFloat.ToString(CultureInfo.CurrentCulture), "Success at last!");
}
Обратите внимание, что я всегда предоставляю IFormatProvider
параметр, хотя он подразумевается и предполагается, что CultureInfo.CurrentCulture
, Причина в том, что я хочу общаться с коллегами-разработчиками: это то, что будет отображаться для конечных пользователей. Это одна из причин, почему FxCop рассматривает пропуск этого параметра как ошибку.
InvariantCulture, с другой стороны, должен использоваться для надежного преобразования одного из классов, упомянутых выше, в его текстовое представление. Так что если вы хотите, например, передать DateTime
, float
, double
или аналогичный объект через сеть, сохраните его в базе данных или какой-либо текстовый файл (включая XML), вы всегда должны использовать InvariantCulture
:
float someFloat = 1234.56f;
// yields 1234.56
string internalFloat = someFloat.ToString(CultureInfo.InvariantCulture);
DateTime now = DateTime.UtcNow;
// yields something like 04/16/2011 19:02:46
string internalDateAndTime = now.ToString(CultureInfo.InvariantCulture);
Следует отметить, что формат даты / времени, предлагаемый InvariantCulture
на самом деле точно так же, как en-US. Хотя это надежно, это не совсем правильно. Что действительно нужно использовать, так это ISO8601 сменный формат даты и времени. По какой-то причине Microsoft даже не предоставляет такой шаблон (наиболее близкими являются шаблон Sortable - "s" и универсальный шаблон - "u", который напоминает только формат ISO8601), вам необходимо создать свой собственный файл следующим образом:
const string iso8601Pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'";
string iso8601Formatted = now.ToString(iso8601Pattern);
Довольно важное примечание: IFormatProvider
здесь действительно требуется, так как пропуск этого параметра может привести к серьезным ошибкам. Однажды мне пришлось исправить дефект на французской ОС. Код был такой:
float dbVersion = // some kind of logic that took float from database string versionString = dbVersion.ToString(); // culture-aware formatting used Version ver = new Version(versionString); // exception thrown here
Причина была очень простой: форматирование с плавающей запятой на французской ОС (с французским региональным форматированием) было отформатировано примерно на 10,5 и Version
Класс требует культурально-инвариантного ввода.
CurrentUICulture отвечает за загрузку соответствующих переводимых ресурсов для вашего приложения. То есть его следует использовать для отображения правильных текстовых сообщений, цветов и изображений.
В приложении Asp.Net, если вы хотите по какой-то причине реализовать механизм локализации CSS (возможность переопределять определения CSS для каждого языка), CurrentUICulture
хороший способ пойти (при условии, что вы действительно читаете это свойство из веб-браузера).
Аналогично, если вы хотите реализовать механизм переключения языков, CurrentUICulture
это тот, который должен быть переопределен.
InstalledUICulture подключено к локали интерфейса пользователя по умолчанию для ОС. Как говорится в MSDN:
Это свойство является эквивалентом GetSystemDefaultUILanguage в Windows API.
Чтобы действительно понять, что это за свойство, нам нужно углубиться в некоторую теорию. Существуют разные линейки продуктов Windows:
- один язык (например, английский, французский, немецкий, японский и т. д.)
- MUI (многоязычный пользовательский интерфейс - английская базовая ОС и языковые пакеты)
Для одноязычных продуктовых линеек InstalledUICulture всегда будет возвращать язык операционной системы, тогда как для MUI он всегда должен возвращать английский (США) aka en-US. Это полезно? Я не знаю, мне никогда не нужна была такая информация. И лично я не видел программу, которая бы использовала это свойство.
Взято из этого ответа:
CurrentCulture - это.NET-представление языка пользователя системы по умолчанию. Это контролирует число по умолчанию, форматирование даты и тому подобное.
CurrentUICulture относится к языку пользовательского интерфейса по умолчанию - настройке, введенной в Windows 2000. Это в первую очередь касается части локализации / перевода пользовательского интерфейса вашего приложения.
Независимо от региональных параметров, в которых настроена система, это будут "текущие" значения в вашем.NET-приложении.
Часто они оба одинаковы. Но в моей системе они были бы другими: я предпочитаю свои цифры и даты в немецком формате, поэтому CurrentCulture будет немецким, но я также предпочитаю все свои приложения на английском языке, поэтому CurrentUICulture будет английским.