NSDateFormatter doesn't show time zone abbreviation for Asia/Kolkata for the z or zzz specifier, just the GMT offset
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.
- Peter Edberg
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.
- Peter E
---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
Issue in formatting date string Swift 3
Apple doc for TimeZone(abbreviation:)
:
In general, you are discouraged from using abbreviations except for unique instances such as “GMT”. Time Zone abbreviations are not standardized and so a given abbreviation may have multiple meanings.
Does AMST represents "Amazon Summer Time" (UTC-3) or "Armenia Summer Time" (UTC+5)? See: https://www.timeanddate.com/time/zones
That's probably why it can't detect the proper timezone to use.
Solutions I can propose:
- If you know which timezone AMST is:
- replace AMST by UTC-3 or UTC+5 in the date string
- remove AMST from the date string and use
dateFormatter.timeZone = TimeZone(secondsFromGMT: -3 or 5 * 3600)
- Have your source output a more precise timezone.
Note the following code, where AMST is understood correctly:
let df = DateFormatter()
df.locale = Locale.init(identifier: "pt_BR") // assuming AMST is Amazon Summer Time (UTC -3)
df.dateFormat = "HH:mm:ss z"
print(df.date(from: "16:18:43 AMST")) // Optional(2000-01-01 19:18:43 +0000)
But as soon as you include English day or month names (e.g. Fri or Dec) it will produce nil
(because they aren't in Portuguese).
my NSDateFormatter works only in the iPhone simulator
This code seems to work correctly against the "GMT" tag.
NSString *strPubDate = @"Fri, 8 May 2009 08:08:35 GMT";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"EEE, d MMM yyyy HH:mm:ss zzzz"];
NSDate *myDate = [dateFormatter dateFromString:strPubDate];
RFC822 Date and Time specs use a few "zone" tags and I found the correct symbol to parse the "GMT" tag Format String for the iPhone NSDateFormatter
- z~zzz: (Specific GMT Timezone Abbreviation)
- zzzz: (Specific GMT Timezone Name)
- Z: +0000 (RFC 822 Timezone
Thanks for all your help!
Display local time zone abbreviation using DateFormatter
Look at the Unicode Date Formatting Patterns:
Probably you want the pattern v
:
The short generic non-location format. Where that is unavailable, falls back to the generic location format ("VVVV"), then the short localized GMT format as the final fallback.
or z
:
The short specific non-location format. Where that is unavailable, falls back to the short localized GMT format ("O").
Note that time zone names are connected to language and setting posix
locale will probably break that.
You could also ask for the abbreviation directly and include it in your format explicitly:
"h:mma, '\(TimeZone.current.abbreviation() ?? "")' EE dd MMM"
How to format the date to IST?
I've tried several of scenarios of timezone formatters according to the Apple's official docs and the Unicode date-formatter standards.
I inited the timezone like this:
NSTimeZone *_timezone = [NSTimeZone timeZoneWithName:@"IST"];
that presented the proper timezone to me with +0530
offset, so that was used for the instance of my NSDateFormatter
.
NSDateFormatter *_dateFormatter = [[NSDateFormatter alloc]init];
[_dateFormatter setTimeZone:_timezone];
here is the list about I've experienced with different format-scpecifiers:
z
=GMT+0530 IST
zz
=GMT+0530 IST
zzz
=GMT+0530 IST
zzzz
=India Standard Time IST
zzzzz
=India Standard Time IST
it seemed that none of the standard format-specifiers could provide the actual "IST"
only as string, a match was the "India Standard Time IST"
with format specifier zzzz
and zzzzz
– but you can see the "GMT+0530 IST"
still contains it with the rest of the formatters.
NOTE: the other format specifiers like Z
, v
, V
, x
or X
did not seem useful either.
I've read more about format specifiers, the docs says about using z
:
The short specific non-location format (e.g. PDT). Where that is unavailable, falls back to the short localized GMT format.
that means to me, the actual short specific non-location format for India Standard Time is not available via NSDateFormatter
directly – or for some reason is specified as "GMT+0530 IST"
not as short "IST"
†.
on the other hand, I'm not sure whether the long specific non-location format is accepted on your server side (aka "India Standard Time IST"
), or the timezone must be marked by string "IST"
only.
I'm afraid if that latest format is expected only you will need to add it manually and inelegantly, like:
[_dateFormatter setDateFormat:@"dd-MMM-yyyy HH:mm:ss"];
NSString *_date = [[_dateFormatter stringFromDate:[NSDate date]] stringByAppendingString:@" IST"];
NOTE: I've also spotted the months' names should be capitalised as well, I'm not sure that is another expectation or the generic capitalisation of months' names (like e.g. "Jul", "Sep" etc...) is good enough for your server side – I did not take care of capitalising them in my current answer.
† I have not found any standard which to be supposed to describe the actual short format, so based on the unicode standards I would assume the "IST"
should be the shortened format against the "GMT+0530 IST"
– but that is based on my personal speculation only.
NSDateFormatter output difference from iPadOS 13 to 14
Foundation's date and time APIs are built on top of a version of ICU that ships with Apple platforms. Between OS releases, both Foundation and ICU code receive updates, which fix old bugs, and occasionally introduce new bugs. At whatever API layer the change here has manifested (and whether this is considered a bug at that layer), you're seeing the consequence of code having changed.
The behavior here does not look right, but luckily, a locale of en_US_POSIX
(which you should likely be setting anyway) resolves the issue.
NSDate coming null in iOS
Your input string can be parsed with a format of @"EEE MMM d HH:mm:ss VVV yyyy"
.
Related Topics
Could Not Cast Value of Type 'Uitableviewcell' to '(Appname).(Customcellname)'
iOS Check If Application Has Access to Microphone
React Native Xcode Project Product Archive Fails with Duplicate Symbols for Architecture Arm64
Swift 3 - How to Make Timer Work in Background
How Detect Swipe Gesture Direction
How to Convert Uicolor Value to a Named Color String
Get Name of Airplay Device Using Avplayer
Cannot Assign to Property in Protocol - Swift Compiler Error
How to Install iOS 7.0 and iOS 8.0 Simulators in Xcode 6.1
How to Get the Front Camera in Swift
Path Extension and Mime Type of File in Swift
Can't Load Uiviewcontroller Xib File in Storyboard in Swift
Does Webkit in iOS 11 (Beta) Support Webrtc
Constant Movement in Spritekit
How to Find the Address of a Stack Trace in Lldb for iOS
Instagram Hooks Pre-Select Media Issue
How to Install an Unsigned IPA File on My Device Using an Apple Developer Account