TOC

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.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!