NSDateFormatter не показывает сокращение часового пояса для "Азии / Калькутты" для спецификатора "z" или "zzz", только смещение по Гринвичу - PullRequest
6 голосов
/ 31 января 2012

На iOS5-симуляторе и устройстве NSDateFormatter не показывает сокращение часового пояса для "Asia / Kolkata" для спецификатора "z" или "zzz".

NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"Asia/Kolkata"];
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
dateFormatter.dateFormat = @"z"; // or @"zzz"
dateFormatter.timeZone = timeZone;

NSLog(@"date string: %@", [dateFormatter stringFromDate:[NSDate date]]); // "GMT+05:30", expected "IST"
NSLog(@"time zone abbreviation: %@", [timeZone abbreviationForDate:[NSDate date]]); // "IST"

Я ожидаю, что вышеприведенный код выведет:

IST
IST

но выводит:

GMT+05:30
IST

РЕДАКТИРОВАТЬ

Задание локали для индийской локали, похоже, не помогает.

NSLocale *indianEnglishLocale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_IN"] autorelease];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"Asia/Kolkata"];
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setLocale:indianEnglishLocale];
[dateFormatter setDateFormat:@"z"]; // or @"zzz"
[dateFormatter setTimeZone:timeZone];

NSLog(@"date string: %@", [dateFormatter stringFromDate:[NSDate date]]); // "GMT+05:30", expected "IST"
NSLog(@"time zone abbreviation: %@", [timeZone abbreviationForDate:[NSDate date]]); // "IST"

Я ожидаю, что вышеприведенный код выведет:

IST
IST

, но он выдаст:

GMT+05:30
IST

Это ошибка?Я делаю что-то неправильно? Люди упоминали, что в NSDateFormatter есть ошибки, особенно когда в строке формата указан часовой пояс.Может ли это быть одной из тех ошибок?

1 Ответ

14 голосов
/ 01 февраля 2012

С http://www.cocoabuilder.com/archive/cocoa/310977-nsdateformatter-not-working-on-ios-5.html#311281

Изменение в разборе сокращенных имен часовых поясов в iOS 5.0 является результат преднамеренного изменения в библиотеке ICU 4.8 с открытым исходным кодом (и данные CLDR 2.0 с открытым исходным кодом, которые он использует), модифицированная версия из которых используется для реализации некоторых из NSDateFormatter функциональность.

Проблема заключается в следующем: с short форматами часового пояса, как указано в z (= zzz) или v (= vvv), может быть много двусмысленности. Например, "ET" для восточного времени »может относиться к разным часовым поясам во многих разные регионы. Для повышения надежности форматирования и анализа краткие формы используются только в локали, если флаг "cu" (обычно используется) установлен для локали. В противном случае используются только длинные формы (для как форматирование, так и разбор).

Для локали "en" (= "en_US") флаг cu устанавливается для таких метазонов, как как Аляска, Америка_Центральный, Америка_Восток, Америка_Гора, Америка - Тихоокеанский, Атлантический, Гавайи - Алеутский и GMT. Это не набор для Европы_Центральный.

Однако для локали en_GB флаг cu имеет значение , установленное для Europe_Central.

Итак, форматер установлен для стиля короткого часового пояса "z" или "zzz" и локали «en» или «en_US» не будут анализировать «CEST» или «CET», но если локаль вместо того, чтобы установить «en_GB», он будет анализировать их. Стиль "GMT" будет проанализировано всеми.

Если форматтер установлен для стиля длинного часового пояса "zzzz", и locale - любой из en, en_US или en_GB, а затем любой из следующих будет проанализирован, потому что они однозначны: "Тихоокеанское летнее время" "Центральноевропейское летнее время" "Центральноевропейское время"

Надеюсь, это поможет.

  • Питер Эдберг

С http://www.cocoabuilder.com/archive/cocoa/313301-nsdateformatter-not-working-on-ios-5.html#313301

Хит, Да, вы правы, для приведенного выше примера, [dateFormatter stringFromDate: [NSDate date]] должен использовать короткий Название часового пояса "IST". Тот факт, что это не из-за недостатка в данных локали "en_IN" в версиях данных CLDR, используемых ICU в текущие выпуски OSX и iOS (CLDR 1.9.1 и 2.0 соответственно). Язык "en_IN" в этих версиях CLDR не перекрывал или дополнить любые данные об именах часовых поясов из базовой локали "en", чье содержимое по умолчанию для "en_US".

Это уже исправлено в выпуске CLDR 21, выходящем через несколько дней. Это включается в ICU 49, который будет взят в будущие выпуски OSX и iOS.

  • Питер E

--- Редактировать ---

В соответствии с документацией Unicode для форматов и их правил , формат V может быть лучшим выбором:

... в том же формате, что и z, за исключением того, что аббревиатуры часового пояса метазоны должны отображаться, если они доступны, независимо от значения [the] обычно используемого [flag].

В моем случае для следующего кода:

NSLocale *indianEnglishLocale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_IN"] autorelease];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"Asia/Kolkata"];
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setLocale:indianEnglishLocale];
[dateFormatter setDateFormat:@"V"];
[dateFormatter setTimeZone:timeZone];

NSLog(@"V date string: %@", [dateFormatter stringFromDate:[NSDate date]]);

Я получаю следующий вывод:

V date string: IST
...