Is NSDateFormatter correctly format my time zone? - ios

I am using this code to create timezone stamps for the server interaction.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSLocale *enUSPOSIXLocale = [NSLocale localeWithLocaleIdentifier:#"en_US_POSIX"];
[dateFormatter setLocale:enUSPOSIXLocale];
//This NSDateFormatter will return timezone in format "UTC+XX:XX"
[dateFormatter setDateFormat:#"'UTC'ZZZZZ"];
NSString *formattedTimeZone = [dateFormatter stringFromDate:[NSDate date]];
return formattedTimeZone;
Response of this code is : UTC+08:00 and so on it is depending in with time zone you are.
But in one case when i am in UTC+00:00 timezone. The response is UTCZ instead of UTC+00:00.
Could you please explain why only this timezone has a formatting problem ?

There's no formatting problem here - or at least, no bug in NSDateFormatter. It's behaving exactly as documented. From Unicode TR35-31, for 'Z' repeated 5 times:
The ISO8601 extended format with hours, minutes and optional seconds fields. The ISO8601 UTC indicator "Z" is used when local time offset is 0. This is equivalent to the "XXXXX" specifier.
If you really, really want to avoid the Z, it looks like you should use xxxxx, documented as:
The ISO8601 extended format with hours, minutes and optional seconds fields. (The same as XXXXX, minus "Z".)
Note that if you only ever want hours and minutes, never seconds, you should use ZZZ or xxx instead. It's unlikely to make any difference for time zones in modern times - sub-minute offsets were phased out a long time ago.

Related

Why 'Z' is at the end of date while converting from UTC to BST?

Tried to convert from UTC to BST (British summer time) using date format. But it's gives me 'Z' at the end of the date. It is working for from UTS to IST conversation.Below is my code.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[NSLocale currentLocale]];
[dateFormatter setDateFormat:#"dd'-'MM'-'yyyy HH':'mm':'ss ZZZZZ"];
NSMutableString *dateString = [NSMutableString stringWithFormat:#"%#", [dateFormatter stringFromDate:[NSDate date]]];
NSLog(#"%#",dateString); // This prints 20-11-2019 12:49:02 Z
Can any one know why does this happen. Any issue with the code or need to change something?
Replace the ZZZZZ in your date format with xxxxx. The use of ZZZZZ will give -99:99 unless the user is in the GMT timezone in which case it simply gives Z. xxxxx will give -99:99 regardless the user's timezone.
You can see specific details in the Unicode specification.
For ZZZZZ it states:
-08:00
-07:52:58
The ISO8601 extended format with hours, minutes and optional seconds fields. The ISO8601 UTC indicator "Z" is used when local time offset is 0. This is equivalent to the "XXXXX" specifier.
For XXXXX it states:
-08:00
-07:52:58
Z
The ISO8601 extended format with hours, minutes and optional seconds fields. The ISO8601 UTC indicator "Z" is used when local time offset is 0. (The same as xxxxx, plus "Z".)
For xxxxx it states:
-08:00
-07:52:58
The ISO8601 extended format with hours, minutes and optional seconds fields. (The same as XXXXX, minus "Z".)

NSDateFormatter "HH" returning am/pm on iOS 8 device [duplicate]

This question already has answers here:
What is the best way to deal with the NSDateFormatter locale "feature"?
(4 answers)
Closed 7 years ago.
I am stumped right now. I have been happily using NSDateFormatter with no problems, but today I noticed that one of my apps is giving me crazy results on an iPhone 6 plus device with iOS 8.1.3 - while it seems to be fine on other devices/simulator. Looking into it there is this code:
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"UTC"]];
[dateFormatter setDateFormat:#"HH"];
NSInteger hour= [[dateFormatter stringFromDate:datetime] integerValue];
This results (on the device) to 0-12 hour notation, because for a reason that is beyond me, if I print [dateFormatter stringFromDate:datetime] at that point I get "4 pm"!
What am I missing?
Edited:
To see the problem, in your phone settings select a region that defaults to a 24-hour time, for example "United Kingdom" or "France". Then, disable the "24 hour time" from the settings. Now if you create an NSDateFormatter without setting its locale, "HH" will not work.
To circumvent this problem, set the locale (even to the same one the phone is at that moment) e.g. for the above code we could add:
dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
Any locale will work, even en_GB. This is obviously a bug, and not some sort of strange representation of the unicode standard, because if you have set a region that defaults to 12 hour time, the "24 hour time" slider does not affect how "HH" works, while if you are on a region that defaults to 24 hour time, then that slider in the settings will affect how your code works.

Rails date to NSDate

I am trying to convert date from rails api to NSDate object.
The response date from api is 2014-11-05T16:29:09.614Z
What does .614Z mean?
The int before the Z are the milliseconds, the Z stand for Zulu which is the time zone:
From http://en.wikipedia.org/wiki/Coordinated_Universal_Time:
The UTC time zone is sometimes denoted by the letter Z—a reference to
the equivalent nautical time zone (GMT), which has been denoted by a Z
since about 1950. The letter also refers to the "zone description" of
zero hours, which has been used since 1920 (see time zone history).
Since the NATO phonetic alphabet and amateur radio word for Z is
"Zulu", UTC is sometimes known as Zulu time.
Thus you time format is:
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSSZ"];
If you include the Z like in the example above the date will correctly converted to the devices current timezone.

NSDateFormatter returns different date for simulator and device. [duplicate]

I have several date strings that I need to convert to NSDates.
My parsing code is the following:
NSString *s = [pair objectForKey:#"nodeContent"];
NSDateFormatter *f = [[NSDateFormatter alloc] init];
[f setDateFormat:#"yyyy-MM-dd'T'HH:mm:ssZZ"];
self.date = [f dateFromString:s];
The above code works fine in all the devices and simulators we've tested.
The strange thing is that when the above code runs on any iPhone 5 running iOS 6.1 or 7.0.x , the line self.date = [f dateFromString:s]; returns nil every time.
I have checked and the string s exists and contains the same characters when compared side-by-side with a device that does parse the date correctly.
This is an example date string:
`2013-10-31T21:50:00-06:00'
Am I missing something here?
It's because you are not setting the date formatter's locale to the special en_US_POSIX locale. Most likely your iPhone 5 has a different setting for the 24-hour setting.
You need to set the special locale whenever you parse a fixed format string.

Nsdateformatter + Timezone issue

I am trying to parse this date timestamp
Begin to string:
Wed, 11 Sep 2013 08:51:41 EEST
This issue with only
EEST
, I have tried z or zzz or V, nothing happened. Date formatter always getting NULL.
While I am cutting EEST from string, everything goes OK.
Could anyone suggest, how to solve this issue?
Thanks
UPDATE:
dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"en_EN_POSIX"]];
[dateFormat setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"EEST"]];
[dateFormat setDateFormat:#"EEE, dd MMM yyyy HH:mm:ss V"];
dateFromString = [dateFormat dateFromString:beginString];
Your solution to this problem is to change the locale to en_GB and the date formatter will be able to parse your date string properly.
Here is the explanation from the Apple developer bug reporting team in reply to radar #9944011:
This is an intentional change in iOS 5. The issue is this: With the short 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). This is a change in open-source CLDR 2.0 / ICU 4.8, which is the basis for the ICU in iOS 5, which in turn is the basis of NSDateFormatter behavior.
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"
Try this instead:
NSString *beginString = #"Wed, 11 Sep 2013 08:51:41 EEST";
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"en-GB"]];
[dateFormat setDateFormat:#"EEE, dd MMM yyyy HH:mm:ss zzz"];
NSDate *dateFromString = [dateFormat dateFromString:beginString];
See details & explanation here

Resources