This article has been localized into Russian by the community.
A special thanks goes out to user #436 for the Russian translation of this article: Nataliya Abragamovich
Класс CultureInfo
В последних двух статьях мы говорили о том, насколько полезен класс CultureInfo, когда требуется полный контроль над отображением чисел и дат в приложении. Мы также говорили о том, как можно проверить, какой язык и региональные параметры приложения используются в качестве резервного и как их изменить. Имея в виду всё это, пришло время углубиться в реальный класс CultureInfo, чтобы увидеть, как мы можем использовать его в полной мере.
Быстрое напоминание перед началом работы: класс CultureInfo является частью System.Globalization, поэтому не забудьте импортировать его всякий раз, когда вы пробуете примеры:
using System.Globalization;
Нейтральные и специфические культуры
В предыдущих примерах в этой главе, мы использовали только определенные культуры, которая является культурой, которая определяет язык и страну/регион. Пример этого en-US культура, где четко говорится, что нужный язык должен быть английский и регион США. Альтернативой этому является культура en-GB , которая является тем же языком (английским), но из региона Великобритании вместо США.
Будут моменты, когда эти различия важны для вас, и в этом случае вы должны использовать эти региональные версии класса CultureInfo. С другой стороны, будут также ситуации, когда английский язык - это просто язык, и вы не хотите привязывать этот язык к конкретной стране или региону. Для этого .NET framework определяет так называемые нейтральные культуры, которые определяют только язык. Фактически, как en-US, так и en-GB наследуют от такой нейтральной культуры (что имеет смысл, поскольку они используют один и тот же язык!) и вы можете получить к нему доступ из свойства Parent. Позвольте мне проиллюстрировать на примере:
CultureInfo enGb = new CultureInfo("en-GB");
CultureInfo enUs = new CultureInfo("en-US");
Console.WriteLine(enGb.DisplayName);
Console.WriteLine(enUs.DisplayName);
Console.WriteLine(enGb.Parent.DisplayName);
Console.WriteLine(enUs.Parent.DisplayName);
Не очень полезный пример, но он должен дать вам лучшее представление о внутренней структуре класса CultureInfo. Выходные данные должны выглядеть следующим образом:
English (United Kingdom)
English (United States)
English
English
Получение правильного CultureInfo
Из наших предыдущих примеров вы видели, что мы можем получить нужный класс CultureInfo, передав идентификатор языка страны/региона конструктору класса. Но поскольку вы можете искать нейтральную культуру, как описано выше, Вы также можете просто передать идентификатор языка:
CultureInfo en = new CultureInfo("en");
.NET framework будет возвращать английский, регион-нейтральных значений экземпляра для вас. Для получения полного списка возможных идентификаторов языка и/или языка-страны/региона, я предлагаю Вам проверить MSDN documentation.
Другой способ выявления конкретного языка это так называемым код (код языка). Вы найдете его как свойство в существующих экземплярах CultureInfo, но, если вы знаете идентификатор, Вы также можете использовать его для создания экземпляра объекта CultureInfo. Например, LCID для en-US равен 1033:
CultureInfo enUs = new CultureInfo(1033);
Однако в большинстве ситуаций гораздо проще использовать спецификатор языка-страны/региона, как было показано ранее.
Получение списка доступных культур
Теперь мы можем получить определенную культуру и использовать ее для различных целей, но, возможно, вам нужен список доступных культур, например, чтобы пользователь мог выбрать язык и/или страну/регион. К счастью, .NET framework делает это для нас легко - вот пример:
CultureInfo[] specificCultures = CultureInfo.GetCultures(CultureTypes.SpecificCultures);
foreach (CultureInfo ci in specificCultures)
Console.WriteLine(ci.DisplayName);
Console.WriteLine("Total: " + specificCultures.Length);
Как видно из первой строки кода, я использую статический методGetCultures класса CultureInfo для получения списка языков и региональных параметров. Для этого требуется параметр CultureTypes, который указывает, какие культуры вы ищете. В данном случае я попросил указать конкретные культуры, которые, как мы говорили ранее, являются культурами, связанными как с языком, так и со страной/регионом. Это довольно длинный список, кстати - на этом компьютере, я получаю в общей сложности 563 существующих культур!
Но, возможно, Вас больше интересуют нейтральные культуры? Это, например, имело бы смысл, если бы вы строили список доступных языков, не заботясь о том, с какой страной или регионом они связаны. Сделать это так же просто, как изменить параметр CultureTypes:
CultureInfo[] neutralCultures = CultureInfo.GetCultures(CultureTypes.NeutralCultures);
foreach (CultureInfo ci in neutralCultures)
Console.WriteLine(ci.DisplayName);
Console.WriteLine("Total: " + neutralCultures.Length);
Поступая таким образом, вы увидите, что там не так много нейтральных культурах существуют особые культур - на моем компьютере/.Net версии, в результате в общей сложности 280 нейтральными.
Важные свойства & методы CultureInfo
Как только у вас есть экземпляр класса CultureInfo, вы сразу получаете доступ к очень широкому спектру полезных свойств и методов. Они могут помочь вам сделать много полезных вещей, в области культуры - давайте посмотрим на некоторые из них!
DateTimeFormat
С помощью свойства DateTimeFormat можно получить доступ к сведениям о форматировании даты и времени, а также к большому количеству полезной информации о календаре для данного языка и региональных параметров. Хороший пример этого FirstDayOfWeek или CalendarWeekRule свойства - они могут сказать вам, на какой день недели начинается (обычно воскресенье или понедельник) и как первая календарная неделя года определяется (например, только первый день или первую неделю):
CultureInfo enUs = new CultureInfo("en-US");
Console.WriteLine("First day of the: " + enUs.DateTimeFormat.FirstDayOfWeek.ToString());
Console.WriteLine("First calendar week starts with: " + enUs.DateTimeFormat.CalendarWeekRule.ToString());
Попробуйте изменить экземпляр CultureInfo на свой или другой известный язык, чтобы увидеть, как эти свойства меняются!
Другая интересная вещь заключается в том, что вы можете получить информацию о названия месяцев и дней недели на конкретную культуру, используя такие свойства, как в свойстве MonthNames и методы, например GetMonthName(). Вот краткий пример:
CultureInfo enUs = new CultureInfo("en-US");
foreach (string monthName in enUs.DateTimeFormat.MonthNames)
Console.WriteLine(monthName);
Console.WriteLine("Current month: " + enUs.DateTimeFormat.GetMonthName(DateTime.Now.Month));
И то же самое можно сделать в течение нескольких дней, используя свойствоDayNames и методGetDayName () :
CultureInfo enUs = new CultureInfo("en-US");
foreach (string dayName in enUs.DateTimeFormat.DayNames)
Console.WriteLine(dayName);
Console.WriteLine("Today is: " + enUs.DateTimeFormat.GetDayName(DateTime.Now.DayOfWeek));
Существует множество более полезных свойств и методов DateTimeFormat, например, DateSeparator, YearMonthPattern и так далее. Взгляните на документацию - там вполне может быть решение вашей проблемы с датой/временем: документация DateTimeFormatInfo .
NumberFormat
Подобно тому, как DateTimeFormat содержит сведения о датах, можно получить доступ к сведениям о том, как определенный язык и региональные параметры обрабатывает числа из свойства NumberFormat. Эта информация используется каждый раз, когда вы запрашиваете визуальное представление числа, например, при преобразовании его в строку и записи в консоль, но вы также можете получить доступ к информации самостоятельно, используя свойства и методы свойства NumberFormat-вот пример:
CultureInfo enUs = new CultureInfo("en-US");
Console.WriteLine(enUs.DisplayName + ":");
Console.WriteLine("NumberGroupSeparator: " + enUs.NumberFormat.NumberGroupSeparator);
Console.WriteLine("NumberDecimalSeparator: " + enUs.NumberFormat.NumberDecimalSeparator);
CultureInfo deDe = new CultureInfo("de-DE");
Console.WriteLine(deDe.DisplayName + ":");
Console.WriteLine("NumberGroupSeparator: " + deDe.NumberFormat.NumberGroupSeparator);
Console.WriteLine("NumberDecimalSeparator: " + deDe.NumberFormat.NumberDecimalSeparator);
Мы используем свойства NumberGroupSeparator и NumberDecimalSeparator для получения информации о том, как отображается число (например, 1000).00 или 1.000, 00) для английской и немецкой культур. Если вы посмотрите, вы найдете подходящие свойства для валют (CurrencyGroupSeparator или CurrencyDecimalSeparator), а также процентов (PercentGroupSeparator или PercentDecimalSeparator).
Говоря о валюте, свойство NumberFormat также может подсказать, какой символ используется данной культурой для отображения денежной суммы - просто используйте свойство CurrencySymbol:
CultureInfo enUs = new CultureInfo("en-US");
Console.WriteLine(enUs.DisplayName + " - currency symbol: " + enUs.NumberFormat.CurrencySymbol);
CultureInfo deDe = new CultureInfo("de-DE");
Console.WriteLine(deDe.DisplayName + " - currency symbol: " + deDe.NumberFormat.CurrencySymbol);
CultureInfo ruRu = new CultureInfo("ru-RU");
Console.WriteLine(ruRu.DisplayName + " - currency symbol: " + ruRu.NumberFormat.CurrencySymbol);
Все эти свойства хорошо известны, но в большинстве случаев вам не придется иметь с ними дело, так как C# будет молча использовать информацию для форматирования чисел, процентов и валют для вас, если вы укажете правильную строку формата при превращении числа в строку.
Имена & идентификаторы
Наконец, давайте посмотрим на свойства, которые представляют экземпляр CultureInfo. Мы уже использовали некоторые из них, например, Name и DisplayName, но как они на самом деле работают? Во-первых, вот список доступных свойств, используемых для идентификации CultureInfo:
- Name определит CultureInfo в формате код языка-страна / регион-код, например "en-US" для английского языка в США, en-GB для английского языка в Великобритании и так далее. Если страна/регион не указаны, будет возвращена только первая часть, например " en " для английского языка.
- TwoLetterISOLanguageName будет делать почти то же самое, что и имя, но он будет возвращать только код языка, независимо от того, была ли указана страна/регион или нет. Например, "en" будут возвращены как "en-US" и "en-GB". Возвращаемые буквы указываются в ISO 639-1 standard.
- ThreeLetterISOLanguageNameработает так же, как TwoLetterISOLanguageName, но возвращает три буквы вместо двух, как указано в ISO 639-2 standard.
- EnglishName вернет название языка (на английском языке). Если страна / регион были указаны, они будут добавлены к результату в скобках.
- NativeName возвращает имя языка (на языке, указанном экземпляром CultureInfo). Если страна / регион были указаны, они в скобках будут добавлены к результату.
Итог
Как вы можете понять из этой статьи, работа с культурой в целом-непростая задача. К счастью для нас .Net и делает его намного проще с класса cultureinfo. Он используется во всем приложении при форматировании чисел и дат, но полезно знать, как он работает, чтобы при необходимости можно было изменить поведение. Надеюсь, эта статья научила вас большей части того, что вам нужно знать о классе CultureInfo.