Форматирование данных Используя настройки локали

Разные страны и области имеют различные соглашения для форматирования числовой и основанной на времени информации. Настройки локали предоставляют информацию о форматах, используемых текущим пользователем, и должны быть рассмотрены при записи кода, обрабатывающего бывшие обращенным к пользователю типы данных. Пользователь устанавливает локаль путем выбора области в Настройках на устройствах на iOS и Установках системы на Mac. В то время как приложение работает, пользователь может также изменить настройки локали. Поэтому, если Вы управляете объектами данных в своем коде и затем представляете их пользователю, используйте локаль APIs для форматирования данных правильно.

Вы не должны знать, как отформатировать данные во всех различных локалях. Можно использовать предварительно установленные стили, автоматически генерирующие чувствительные к локали форматы. Можно использовать пользовательские форматы, пока Вы преобразовываете их в чувствительные к локали форматы прежде, чем представить их пользователям. Эта глава объясняет, как записать чувствительный к локали код.

О форматах локали

Локали представляют выбор форматирования для определенного пользователя, не предпочтительный язык пользователя. Они часто - то же, но могут отличаться. Например, носитель английского языка, живущий в Германии, мог бы выбрать English как язык и Германию как область. Текст появляется на английском языке, но даты, времена и числа соблюдают немецкие правила форматирования. День предшествует месяцу, и 24-часовые часы представляют времена, как показано в Таблице 4-1.

Табличные 4-1  Форматы данных в США и Германии

Язык (Область)

Даты

Времена

Числа

Английский язык (США)

Воскресенье, 5 января 2014

05.01.14

7:08:09 PST

7:08

1,234.56

4 567,89$

Английский язык (Германия)

Воскресенье 5 января 2014

01.05.14

7:08:09 PST

07:08

1.234,56

4.567,89€

На Mac можно предварительно просмотреть измененные предпочтения локали в Установках системы. Когда Вы выбираете географическую область из всплывающего меню Области, выборок даты, время, и числовые форматы появляются. Этот снимок экрана показывает демонстрационные форматы данных, когда английский язык является языком, и Япония является областью:

../Art/mac_region_settings_english_japan_2x.png

Пользователи Mac могут также настроить форматы дат, времена и числа путем нажатия кнопки Advanced, как описано в Изменении Предпочтений Языка и Области на Mac.

Используя объект языкового стандарта

NSLocale объект инкапсулирует информацию о стандартах форматирования определенной области. При форматировании бывшего обращенным к пользователю текста Вы передаете NSLocale объект, представляющий выбранную область пользователя. NSLocale класс обеспечивает методы класса для получения объекта языкового стандарта пользователя и другой информации о поддерживаемых локалях.

Получение локали пользователя

Можно получить локаль пользователя с помощью любого currentLocale или autoupdatingCurrentLocale методы класса в NSLocale класс.

Если Вы используете currentLocale метод, значения свойств возвращенного объекта, как гарантируют, не изменятся. Поэтому используйте currentLocale метод, если Вы хотите выполнить операции, которые должны быть непротиворечивыми.

Если Вы используете autoupdatingCurrentLocale когда пользователь изменяет настройки области, метод, значения свойств могут измениться. Если возвращенный объект изменяется, Однако Вы не уведомляетесь.

Для наблюдения предпочтительных изменений локали считайте Регистрацию для Изменений Локали и TimeZone.

Получение информации о локали

Используйте objectForKey: метод экземпляра в NSLocale класс информации о доступе о локали. Например, передайте NSLocaleUsesMetricSystem ключ к этому методу для получения Булевого числа, определяющего, использует ли локаль метрическую систему:

NSNumber *metricSystem = [[NSLocale currentLocale] objectForKey:NSLocaleUsesMetricSystem];

Передайте NSLocaleCurrencySymbol ключ для получения строкового представления обозначения денежной единицы локали:

NSString *currencySymbol = [[NSLocale currentLocale] objectForKey:NSLocaleCurrencySymbol];

Для полного списка ключей свойства локали посмотрите NSLocale Component Keys.

Получение локализованных имен языка и диалекта

Идентификаторы, указывающие языки и диалекты в APIs и именах папок — например, de-CH, en-AU, и pt-PT— не должен быть выведен на экран пользователям. Для получения человекочитаемого, локализованного языка или имени диалекта используйте displayNameForKey:value: метод в NSLocale класс, передавая NSLocaleIdentifier как основной параметр.

Получить локализованное имя для языков и диалектов

  1. Получите язык, который использует приложение.

    NSString *languageID = [[NSBundle mainBundle] preferredLocalizations].firstObject;

    Возвращаемая строка является языком ID, идентифицирующий письменный язык или диалект, как описано на Языке и Локали IDs.

  2. Получите связанный объект языкового стандарта.

    NSLocale *locale = [NSLocale localeWithLocaleIdentifier:languageID];

    При передаче языка ID как локаль параметр ID локаль для языка возвращается. Например, если Вы передаете de-CH как язык, возвращается локаль Швейцарии.

  3. Получите локализованное имя языка.

    NSString *localizedString = [locale displayNameForKey:NSLocaleIdentifier value:languageID];

Формат строки [Language] ([Dialect]). Например, если язык ID de-CH, локализованной строкой языка является «Deutsch (Schweiz)». Если язык ID de, локализованная строка языка является «Deutsch».

Получение специфичных для языка кавычек

Начало и окончание кавычек, варьирующихся по различным языкам, могут быть получены из объекта языкового стандарта. Используйте тот же метод, описанный в Получении Локализованных Имен Языка и Диалекта, чтобы получить локаль по умолчанию для языка, и затем использовать компонентные ключи локали для получения специфичных для языка кавычек.

Создать строку, использующую чувствительные к локали кавычки

  1. Получите язык, который использует приложение.

    NSString *languageID = [[NSBundle mainBundle] preferredLocalizations].firstObject;
  2. Получите связанный объект языкового стандарта.

    NSLocale *locale = [NSLocale localeWithLocaleIdentifier:languageID];
  3. Получите начальные и конечные символы для кавычек от объекта языкового стандарта.

    bQuote = [locale objectForKey:NSLocaleQuotationBeginDelimiterKey];
    eQuote = [locale objectForKey:NSLocaleQuotationEndDelimiterKey];
  4. Отформатируйте строку с помощью чувствительных к локали кавычек.

    quotedString = [NSString stringWithFormat:@"%@%@%@", bQuote, myText, eQuote];

Таблица 4-2 показывает результаты когда myText “@iPhone”для различных областей.

Табличные 4-2  кавычки в Китае, Франции и Японии

Область

quotedString = «% @iPhone %»

Китай

«iPhone»

Франция

../Art/french_iphone.svg

Япония

../Art/japanese_iphone.svg

Форматирование строк

При наличии используйте альтернативное, чувствительное к локали NSString метод для бывшего обращенным к пользователю текста. Существуют чувствительные к локали методы для создания строк с форматами, изменение случая, получение диапазонов в строке и сравнения строк.

Создание отформатированных строк

Как минимум используйте localizedStringWithFormat: метод в NSString класс, не stringWithFormat: метод для форматирования бывшего обращенным к пользователю текста. Простая фиксация к существующему коду должна заменить случаи stringWithFormat: метод с альтернативой localizedStringWithFormat: метод всюду по Вашему коду, как в:

NSString *localizedString = [NSString localizedStringWithFormat:@"%3.2f", myNumber];

Этот метод использует системную локаль. Указать предпочтение локали пользователя, передачу [NSLocale currentLocale] как параметр локали любому initWithFormat:locale: или initWithFormat:locale:arguments: метод. Для лучших результатов используйте специфичные для данных объекты средства форматирования и задайте стили, описанные в Форматировании Дат и времени и Форматировании Чисел.

Изменение случая строк

Процесс изменения случая в строках не является тем же для всех языков. Используйте их чувствительные к локали NSString методы для изменения случая:

Если Вы передаете nil как параметр локали, используется системная локаль, который является неправильным. Указать предпочтение локали пользователя, передачу [NSLocale currentLocale] как параметр локали.

Форматирование дат и времени

Вы используете NSDateFormatter класс для создания представлений локализованной строки NSDate объекты, которые также чувствительны к локали. NSDateFormatter если Вы создаете, объекты часто присоединяются непосредственно к текстовым полям в Интерфейсном файле Разработчика, но NSDateFormatter объекты программно, убедиться использовать методы та локализованная строка возврата представления.

Используя стили заранее назначенной даты и времени

Для получения представления локализованной строки даты и времени с помощью предварительно установленного стиля используйте localizedStringFromDate:dateStyle:timeStyle: метод класса в NSDateFormatter класс:

NSString *localizedDateTime = [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterShortStyle];

Например, укажите средний стиль для сокращения текста — такого как «10 июня 2013» — путем передачи NSDateFormatterMediumStyle как параметр стиля. Укажите короткий стиль для числового только представления — такие как «6/10/13» или «11:03» — путем передачи NSDateFormatterShortStyle как параметр стиля. Таблица 4-3 показывает результаты использования предварительно установленных форматов, когда английский язык является языком, и США являются областью.

Табличная 4-3  Заранее назначенная дата и время разрабатывает на английском языке для США

Стиль

Дата

Время

Описание

Короткий

10.06.13

11:03

Числовой только

Носитель

10 июня 2013

11:03:15

Сокращенный текст

Долго

10 июня 2013

11:03:15 PDT

Полный текст

Полный

Пятница, 10 июня 2013

11:03:15 летнее время Тихого океана

Полные подробные данные

Никакой стиль

Вывод подавлен

Таблица 4-4 показывает результаты передачи NSDateFormatterMediumStyle для стиля даты и NSDateFormatterShortStyle поскольку время разрабатывает для различных языков и областей.

Табличная 4-4  Заранее назначенная дата и время разрабатывает на различных языках и областях

Язык (Область)

Средний стиль

Короткий стиль

Английский язык (США)

6 июня 2013

10:14

Французский язык (Франция)

6 июня 2013

10:14

Китайский язык (Китай)

../Art/chinese_date_year.svg

../Art/chinese_time.svg

Используя пользовательские стили даты и времени

Используйте пользовательские стили даты и времени только, когда предварительно установленные стили не удовлетворят Ваши потребности. Однако преобразуйте свой пользовательский формат в чувствительный к локали формат прежде, чем получить строковые представления даты и времени. dateFormatFromTemplate:options:locale: метод класса в NSDateFormatter класс перестраивает данный шаблон для соблюдения указанной локали.

Получить представление локализованной строки даты и времени с помощью пользовательского стиля

  1. Создайте NSDateFormatter объект.

    NSDateFormatter *dateFormatter = [NSDateFormatter new];
  2. Используйте dateFormatFromTemplate:options:locale: метод класса получить локализованную строку формата от шаблона, который Вы обеспечиваете.

    NSString *localeFormatString = [NSDateFormatter dateFormatFromTemplate:@"dMMM" options:0 locale:dateFormatter.locale];

    Шаблонный параметр dateFormatFromTemplate:options:locale: метод должен придерживаться Технического стандарта № 35 Unicode, описанного в Строках формата Использования для Указания Пользовательских Форматов. Например, шаблон @”dMMM” указывает, что день месяца и сокращения в течение месяца должен быть в строке формата. Порядок символов и любых символов несимвола в шаблоне проигнорирован.

  3. Установите формат NSDateFormatter экземпляр к чувствительной к локали строке формата.

    dateFormatter.dateFormat = localeFormatString;
  4. Используйте stringFromDate: метод для получения представления локализованной строки даты.

    NSString *localizedString = [dateFormatter stringFromDate:[NSDate date]];

Например, если Вы не преобразовываете @“MMM d” представьте в виде строки к чувствительному к локали формату, результаты не локализуются, как показано во втором столбце в Таблице 4-5.

Таблица 4-5  Нелокализованные и локализованные форматы даты в различных областях

Язык (Область)

Дата с помощью строки формата

“MMM d”

Шаблон использования даты

«dMMM»

Английский язык (США)

13 ноября

13 ноября

Французский язык (Франция)

13 ноября

13 ноября.

Китайский язык (Китай)

../Art/chinese_date_incorrect.svg

../Art/chinese_date.svg

Парсинг локализованных строк даты

Пользователь вводит даты с помощью локализованных форматов, так проанализируйте входные строки соответственно. Используйте NSDateFormatter возразите для преобразования локализованной строки в объект даты. Установите стиль средства форматирования даты с помощью одного из предварительно установленных стилей. (Используйте шаблонную строку формата, только если не работает предварительно установленный стиль.) Кроме того, позвольте средству форматирования даты использовать эвристику при парсинге строки.

Преобразовать локализованную строку даты в объект даты

  1. Создайте объект средства форматирования даты.

    NSDateFormatter *dateFormatter = [NSDateFormatter new];
  2. Установите стиль средства форматирования в предварительно установленный стиль.

    dateFormatter.dateStyle = NSDateFormatterMediumStyle;

    Замена NSDateFormatterMediumStyle со стилем Вы ожидаете, что войдет пользователь.

  3. Если входная строка, как ожидают, не будет содержать время, установите стиль времени ни в один.

    dateFormatter.timeStyle = NSDateFormatterNoStyle;
  4. Установите мягкость в YES (включает эвристику).

    dateFormatter.lenient = YES];
  5. Преобразуйте строку в объект даты.

    NSDate *date = [dateFormatter dateFromString:inputString];

Например, если локалью являются США, входная строка 9/3/14, и предварительно установленный стиль NSDateFormatterShortStyle, дата интерпретируется как 2014-09-03 07:00:00 +0000. Однако, если локалью является Германия, дата становится 2014-03-09 08:00:00 +0000.

Форматирование чисел

Настройки локали влияют на формат чисел — таких как десятичное число, тысячи разделителя, валюты и символов процента. Например, номер 1,234.56 отформатирован как 1.234,56 в Италии. Так используйте NSNumberFormatter класс для создания представлений локализованной строки NSNumber объекты.

Используя предварительно установленные стили нумерации

Для получения представления локализованной строки числа с помощью предварительно установленного стиля используйте localizedStringFromNumber:numberStyle: метод класса в NSNumberFormatter класс:

NSString *localizedString = [NSNumberFormatter localizedStringFromNumber:myNumber numberStyle:NSNumberFormatterDecimalStyle];

Таблица 4-6 перечисляет предварительно установленные доступные стили и сравнивает предварительно установленные форматы США с другими областями.

Табличные 4-6  Предварительно установленные стили нумерации на различных языках и областях

Стиль

Отформатированная строка,

Английский язык (США)

Отформатированная строка,

Язык (Область)

Десятичное число

1,234.56

1.234,56

Итальянский язык (Италия)

Валюта

1 234,56$

../Art/chinese_currency.svg

Китайский язык (Китай)

Процент

123 456%

../Art/arabic_percent.svg

Арабский язык (Египет)

Научный

1.23456E+03

1,23456E3

Итальянский язык (Италия)

Обстоятельно объяснить

одна тысяча двести тридцать четыре указывают пять шесть

../Art/chinese_spellout.svg

Китайский язык (Китай)

Парсинг локализованных числовых строк

Пользователь может ввести номера с помощью локализованных форматов, так проанализируйте эти входные строки соответственно. Используйте NSNumberFormatter возразите для преобразования строки в объект числа. Установите стиль средства форматирования числа с помощью одного из предварительно установленных стилей. Кроме того, позвольте средству форматирования числа использовать эвристику при парсинге строки.

Преобразовать локализованную числовую строку в объект числа

  1. Создайте объект средства форматирования числа.

    NSNumberFormatter *numberFormatter = [NSNumberFormatter new];
  2. Установите стиль средства форматирования в предварительно установленный стиль.

    numberFormatter.numberStyle = NSNumberFormatterDecimalStyle;

    Замена NSNumberFormatterDecimalStyle со стилем Вы ожидаете, что войдет пользователь.

  3. Установите мягкость в YES (включает эвристику).

    numberFormatter.lenient = YES;
  4. Преобразуйте строку в объект числа.

    NSNumber *number = [numberFormatter numberFromString:inputString];

Вычислительные даты Используя календари

NSCalendar класс инкапсулирует все региональные различия и сложности календарей, показанных в Таблице 4-7. Эра изменяется более часто в некоторых календарях, чем другие — например, эра в японских календарных изменениях с каждым новым императором. Число месяцев в год может быть 12 или 13. Из года в год продолжительность месяца может варьироваться. Даже в Григорианском календаре, первый день недели может быть субботой, в воскресенье, или в понедельник. NSCalendar объекты знают о часовых поясах и какие области наблюдают летнее время. Календарные вычисления — такие как третий вторник месяца — зависят от календаря и области пользователя.

Табличные 4-7  Изменения в региональных календарях

Единица времени по календарю

Возможные значения

Год

2011, 1432, 2554, 5771

Эра

AD, Heisei

Число месяцев в год

12, 13, переменная

Продолжительности месяцев

С 5 до 31 дня

Первый день недели

В субботу, в воскресенье, в понедельник

Когда изменяются годы

../Art/japanese_years_change.svg

Поэтому используйте NSCalendar класс для всех calendrical вычислений, таких как вычисления числа дней за месяц, вычислительные значения дельты и получение компонентов даты. Можно использовать NSDate объект для внутренних вычислений, но использования NSCalendar объект для вычислений бывших обращенным к пользователю дат.

Для получения календаря для локали пользователя используйте currentCalendar метод класса в NSCalendar класс:

NSCalendar *currentCalendar = [NSCalendar currentCalendar];

Используйте NSDateComponents возразите для доступа к единицам времени по календарю даты.

Получить компоненты даты

  1. Создайте NSDateComponents объект.

    NSDateComponents *components = [[NSCalendar currentCalendar]
        components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit | NSEraCalendarUnit
        fromDate:[NSDate date]];
  2. Получите доступ к значениям в течение дня, месяца, года и эры.

    NSInteger day = [components day];
    NSInteger month = [components month];
    NSInteger year = [components year];
    NSInteger era = [components era];

Для получения дополнительной информации об использовании NSCalendar и NSDateComponents классы, считайте Руководство по программированию Даты и времени или наблюдайте 2013 WWDC: Решения Общих проблем Даты и времени.

Регистрация для изменений локали и часового пояса

Для получения уведомления об изменениях локали добавьте объект как наблюдателя NSCurrentLocaleDidChangeNotification уведомление:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(localeDidChange:) name:NSCurrentLocaleDidChangeNotification object:nil];

Для получения уведомления об изменениях часового пояса наблюдайте NSSystemTimeZoneDidChangeNotification уведомление. Например, если пользователь перемещается, часовой пояс мог бы измениться, в то время как работает Ваше приложение. Долгое время может протечь с прошлого раза Ваше приложение было активно.

Реализуйте метод уведомления изменения, чтобы переформатировать и вывести на экран все бывшие обращенным к пользователю даты, времена и числа с помощью новых настроек локали пользователя.