ios - NSDateFormatter 不为 "Asia/Kolkata"或 "z"说明符显示 "zzz"的时区缩写,仅显示 GMT 偏移量

标签 ios nsdateformatter

在 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"

我希望上面的代码输出:

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

这是一个错误吗?难道我做错了什么? People have mentioned that NSDateFormatter has bugs, especially when a time zone is specified in the format string. Could this be one of those bugs?

最佳答案

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

The change in parsing of abbreviated time zone names in iOS 5.0 is a result of an intentional change in the open-source ICU 4.8 library (and the open-source CLDR 2.0 data that it uses), a modified version of which is used to implement some of the NSDateFormatter functionality.

The issue is this: With the short timezone formats as specified by z (=zzz) or v (=vvv), there can be a lot of ambiguity. For example, "ET" for Eastern Time" could apply to different time zones in many different regions. To improve formatting and parsing reliability, the short forms are only used in a locale if the "cu" (commonly used) flag is set for the locale. Otherwise, only the long forms are used (for both formatting and parsing).

For the "en" locale (= "en_US"), the cu flag is set for metazones such as Alaska, America_Central, America_Eastern, America_Mountain, America_Pacific, Atlantic, Hawaii_Aleutian, and GMT. It is not set for Europe_Central.

However, for the "en_GB" locale, the cu flag is set for Europe_Central.

So a formatter set for short timezone style "z" or "zzz" and locale "en" or "en_US" will not parse "CEST" or "CET", but if the locale is instead set to "en_GB" it will parse those. The "GMT" style will be parsed by all.

If the formatter is set for the long timezone style "zzzz", and the locale is any of "en", "en_US", or "en_GB", then any of the following will be parsed, because they are unambiguous: "Pacific Daylight Time" "Central European Summer Time" "Central European Time"

Hope this helps.

  • Peter Edberg

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

Heath, Yes, you are correct, for the example you provided above, [dateFormatter stringFromDate:[NSDate date]] should use the short time zone name "IST". The fact that it does not is due to a deficiency in the "en_IN" locale data in the versions of CLDR data used by ICU in the current OSX and iOS releases (CLDR 1.9.1 and 2.0 respectively). The "en_IN" locale in those CLDR versions did not override or supplement any of the timezone name data from the base "en" locale, whose default content is for "en_US".

This is already fixed for the CLDR 21 release coming in a few days. That is being incorporated into ICU 49 which will be picked up in future OSX and iOS releases.

  • Peter E

---编辑---

根据 formats 上的 unicode 文档和他们的 rulesV 格式可能是更好的选择:

...the same format as z, except that metazone timezone abbreviations are to be displayed if available, regardless of the value of [the] commonlyUsed [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

关于ios - NSDateFormatter 不为 "Asia/Kolkata"或 "z"说明符显示 "zzz"的时区缩写,仅显示 GMT 偏移量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9084980/

相关文章:

swift - 如何在 Swift 中以短格式获取当前日期

iphone - 从动画 viewWillAppear 停止 transitionFormViewController

ios - 硬件相关 NSDateFormatter dateFromString : bug (returns nil)

swift - NSFormatter 无 dateFromString

ios - DateFormatter 显示不同的日期

ios - 解析日期并将休息日减 1,nsdate

ios - 如何使用 sbjson 在 iOS 中读取 json

ios - 滚动浏览其中包含 Collectionview 的 UITableView 时崩溃

ios - 为什么 Swift 中的 print() 不会在 Objective-C 中将时间戳记录为 NSLog

嵌入 UISplitViewController 时,UINavigationBar 中缺少 iOS11 UISearchBar