对于"z"或"zzz"说明符,NSDateFormatter不显示"Asia/Kolkata"的时区缩写,只是GMT偏移量

Hea*_*ers 7 nsdateformatter ios

在iOS5模拟器和设备上,NSDateFormatter不为"z"或"zzz"说明符显示"Asia/Kolkata"的时区缩写.

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"
Run Code Online (Sandbox Code Playgroud)

我希望上面的代码输出:

IST
IST
Run Code Online (Sandbox Code Playgroud)

但它输出:

GMT+05:30
IST
Run Code Online (Sandbox Code Playgroud)

编辑

将语言环境设置为印度语语言环境似乎没有帮助.

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"
Run Code Online (Sandbox Code Playgroud)

我希望上面的代码输出:

IST
IST
Run Code Online (Sandbox Code Playgroud)

但它输出:

GMT+05:30
IST
Run Code Online (Sandbox Code Playgroud)

这是一个错误吗?难道我做错了什么? 人们已经提到过NSDateFormatter有bug,特别是在格式字符串中指定了时区时.这可能是那些错误之一吗?

Hea*_*ers 14

来自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功能.

问题是:由于z(= zzz)或v(= vvv)指定的短时区格式,可能存在很多歧义.例如,"东部时间"的"ET"可以应用于许多不同区域的不同时区.为了改善格式化和解析可靠性,如果为"cu"(常用)标志设置为"短",则仅在区域设置中使用短格式区域设置.否则,只使用长格式(格式化和解析).

对于"en"语言环境(="en_US"),为诸如Alaska,America_Central,America_Eastern,America_Mountain,America_Pacific,Atlantic,Hawaii_Aleutian和GMT等元区域设置cu标志.它没有为Europe_Central设置.

然而,对于把"zh_CN"区域中,铜标志设置Europe_Central.

因此,为短时区样式"z"或"zzz"和locale"en"或"en_US"设置的格式化程序不会解析"CEST"或"CET",但如果将语言环境设置为"en_GB",它将解析那些."GMT"风格将由所有人解析.

如果格式化程序设置为长时区样式"zzzz",并且语言环境是"en","en_US"或"en_GB"中的任何一个,那么将解析以下任何内容,因为它们是明确的:"Pacific Daylight时间""中欧夏令时""中欧时间"

希望这可以帮助.

  • 彼得埃德伯格

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

希思,是的,你是对的,对于你上面提供的例子,[dateFormatter stringFromDate:[NSDate date]] 应该使用短时区名称"IST".它不是由于ICU在当前OSX和iOS版本(分别为CLDR 1.9.1和2.0)中使用的CLDR数据版本中的"en_IN"区域设置数据不足.这些CLDR版本中的"en_IN"语言环境未覆盖或补充基本"en"语言环境中的任何时区名称数据,其默认内容为"en_US".

这已经在几天内发布了CLDR 21版本.这已被纳入ICU 49,将在未来的OSX和iOS版本中使用.

  • 彼得E.

- -编辑 - -

根据格式及其规则的unicode文档,V格式可能是更好的选择:

...与z的格式相同,除了metazone时区缩写在可用时显示,而不管[common] [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]]);
Run Code Online (Sandbox Code Playgroud)

我收到以下输出:

V date string: IST
Run Code Online (Sandbox Code Playgroud)

  • 我收到了 - inccu而不是IST! (2认同)