On iOS5 simulator and device, NSDateFormatter doesn't show time zone abbreviation for "Asia/Kolkata" for the "z" or "zzz" specifier.
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"
I expect the above code to output:
IST
IST
but it outputs:
GMT+05:30
IST
EDIT
Setting the locale to an indian locale doesn't seem to help.
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"
I expect the above code to output:
IST
IST
but it outputs:
GMT+05:30
IST
Is this a bug? Am I doing something wrong? 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?
From 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.
From 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.
---Edit---
According to the unicode documentation on formats and their rules, the V
format may have been a better choice:
...the same format as z, except that metazone timezone abbreviations are to be displayed if available, regardless of the value of [the] commonlyUsed [flag].
In my case, for the following code:
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]]);
I receive the following output:
V date string: IST