With the Cocoa framework how can I parse @"2008-12-29T00:27:42-08:00" into an NSDate object? The standard -dateWithString:
doesn't like it.

- 54,380
- 8
- 73
- 102

- 2,072
- 1
- 15
- 19
4 Answers
You can use NSDateFormatter to parse dates:
NSDateFormatter* dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
date = [dateFormatter dateFromString:dateStr];
The unicode date format patterns defines the format string you can use with the setDateFormat:
method.
Note that if you're targeting 10.4 then you need to call: [dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
. Not needed for iphone, or leopard as this mode is the default there.

- 17,816
- 3
- 52
- 60

- 5,589
- 1
- 34
- 25
-
+1 for adding unicode date format patterns link. Been looking for something like that for a while. – rein Jul 22 '09 at 21:40
-
1I couldn't get this to work unless I quoted the Z as well like so [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"]; – Kaom Te Mar 25 '10 at 12:10
-
2This will produce wrong result if the user has AM/PM set on his iPhone - AM/PM marker will get added. Also, if the user is using Japanese Imperial calendar this will get you the year in that calendar, not in Gregorian calendar. To get this right you need to explicitly set the locale and calendar on the date formatter. – DenNukem May 31 '11 at 02:22
-
5I can't get this to work for strings formatted like the example in the question, which loosely seems to be RFC 3339 format, but with a colon in the timezone offset (ending in -08:00). The Unicode technical standard you linked at draft #4 is now up to draft #10, and the treatment of Z has changed a little -- it's now accepted up to 4 times and there's a new Appendix J -- but in no case does it accept the "-08:00" format. "GMT-08:00", yes, and "-0800", yes, but not with the colon and without GMT. I needed to parse a date like that and in desperation ended up ripping out the colon before parsing. – metamatt Nov 26 '11 at 08:22
-
@metamatt I am stuck on the same issue. wish i had seen this post before, would have saved close to an hour :( Did u manage to find a better solution in the end than ripping off the colon? – Shyam Bhat Jul 20 '12 at 14:18
-
@shyam No, I moved on, and left that hacky solution in place. – metamatt Jul 20 '12 at 16:39
If you only need to handle the ISO 8601 format (of which that string is an example), you might try my ISO 8601 parser and unparser.

- 95,783
- 15
- 211
- 370
-
2Maybe if the code were licensed with MIT or Apache 2.0. BSD sucks for use with iPhone apps because of the attribution clause, since most apps don't actually distribute documentation with the binary. – Bob Aman Jun 21 '10 at 01:56
Actually, you need to set timezone, calendar and locale. If you don't set locale, an user has AM/PM time enabled the formatter will add AM/PM marker! If you don't set the timezone, it will use the current timezone, but will mark it as "Z" ("Zulu" or GMT). If you do not set calendar, users with Japanese Imperial calendar will have number of years since current Emperor's ascension instead of the number of years since Jesus Christ was born. Be sure to test in all of the scenarios I mentioned!
NSDateFormatter * f = [[NSDateFormatter alloc] init];
[f setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"];
f.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
f.calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
f.locale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"] autorelease];
NSString * str = [f stringFromDate:someDate];
NSDate * date = [f dateFromString:dateStr];

- 8,014
- 3
- 40
- 45
How the time zone is set changed from ios 5 to ios 6. iOS 6 supports the format +01:00 using ZZZZZ but ios 5 doesn't. I solved this issue with this solution which worked for me to parse a date with the following format in ios 5 and 6.
2013-05-07T00:00:00+01:00
NSMutableString *newDate = [date mutableCopy];
NSRange range;
range.location = 22;
range.length = 1;
[newDate replaceCharactersInRange:range withString:@""];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZ"];
NSDate *dateFromString = [[NSDate alloc] init];
dateFromString = [dateFormatter dateFromString:newDate];

- 1,606
- 1
- 13
- 4