46

If I use the following code:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];   
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm"];
NSDate *myDate = [dateFormatter dateFromString:@"2010-01-28T15:22:23.863"];
NSLog(@"%@", [dateFormatter stringFromDate:myDate]);

It is successfully converted to a Date object, however, I cannot seem to format it any other way than yyyy-MM-dd'T'HH:mm, i.e. what gets logged is 2010-01-28T15:22:23

If I change the dateFormat to say [dateFormatter setDateFormat:@"yyyy-MMMM-d'T'HH:mm"]; the Date object is null...

So my ultimate question is how to format an ISO8601 timestamp from a SQL database to use, for instance, NSDateFormatterMediumStyle to return "January 1, 2010"?

asked Feb 4, 2010 at 16:16

rson's user avatar

42

I have a similiar but slightly more complex problem, and I've found a very simple solution!

The problem: My incoming ISO8601 dates look like this: 2006-06-14T11:06:00+02:00 They have a timezone offset at the end.

The solution: Use Peter Hosey's ISO8601DateFormatter which you can download from here.

ISO8601DateFormatter *formatter = [[ISO8601DateFormatter alloc] init];
NSDate *theDate = [formatter dateFromString:dateString];
[formatter release], formatter = nil;

and

ISO8601DateFormatter *formatter = [[ISO8601DateFormatter alloc] init];
NSString *dateString = [formatter stringFromDate:[twitch dateTwitched]];
[formatter release], formatter = nil;

answered Jul 8, 2010 at 8:40

Matthew's user avatar

18 Comments

ISO8601DateFormatter works well, but it is extremely slow. In my tests, parsing that took NSDateFormatter 300ms took ISO8601DateFormatter 7400ms.

Seems to work. How do I edit the format of the output string? I did not find any example or documentation on that. :(

@GangstaGraham: You can turn on a formatter's includeTime property.

|

19

You need another formatter to handle the output. Put this after your code:

NSDateFormatter *anotherDateFormatter = [[NSDateFormatter alloc] init];   
[anotherDateFormatter setDateStyle:NSDateFormatterLongStyle];
[anotherDateFormatter setTimeStyle:NSDateFormatterShortStyle];
NSLog(@"%@", [anotherDateFormatter stringFromDate:myDate]);

answered Feb 4, 2010 at 17:46

osteven's user avatar

osteven

7767 silver badges4 bronze badges

Comments

19

Here is sample code from apple

    NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
    NSDate *date = [formatter dateFromString:dateString];

link:https://developer.apple.com/library/ios/#qa/qa1480/_index.html

danielbeard's user avatar

danielbeard

9,1373 gold badges47 silver badges60 bronze badges

answered Sep 24, 2012 at 11:30

david's user avatar

david

4014 silver badges11 bronze badges

3 Comments

Don't forget to set the POSIX locale as mentioned in that Apple article; otherwise, you could end up with non-conforming dates that include "AM" or "PM", if the user has an odd combination of settings (e.g. UK locale with 12-hour time enabled).

If milliseconds needed, use @"yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS'Z'"

@JoeHughes How do you set POSIX locale?

12

Just to mention that since iOS 6.0 you can use this format:

 yyyy-MM-dd'T'HH:mm:ssZZZZZ

answered Jun 28, 2013 at 10:53

Marcin's user avatar

Marcin

3,7745 gold badges34 silver badges52 bronze badges

5 Comments

Thanks for sharing with us, just what I needed! Dates like 2013-06-28T15:20:55+02:00 --> yyyy-MM-dd'T'HH:mm:ssZZZZZ

Unfortunately this doesn't parse times with UTC time zone designated by a single 'Z' instead of '+hh:mm'. Or does it?

@macbirdie I can confirm that NSDateFormatter does correctly parse dates designated by a single 'Z'. The test string "2010-01-28T15:22:23Z" works with the date format "yyyy-MMMM-d'T'HH:mm:ssZZZZZ". My test platform is iOS7. The 'Z' format is special-cased in the Unicode standard.

Thanks a lot! There is update_date on Facebook. It's like "2014-08-12T16:13:04+0000"

6

I have a very fast C implementation of parsing ISO8601 NSStrings to NSDates in SAMCategories. You can install it with CocoaPods or just copy the files to your project.

Here's how to use it:

[NSDate sam_dateFromISO8601String:@"2013-08-24T06:51:21-07:00"]

It's very robust and supports missing timezones, etc. Like my comment above said, NSDateFormatter was very slow for me when parsing lots of dates. Switching to this implementation helped an immense amount.

This code is used in 6 production apps (including Hipstamatic and Roon) that I've worked on with no known issues. There is a test suite to prevent regression.

In short, I think this is the best way to parse ISO8601 strings in Objective-C.


A short aside, if you're concerned about performance and transfer, sending integers instead of ISO8601 strings is greatly preferred. You can simply convert them into dates with [NSDate dateWithTimeIntervalSince1970:yourInteger]. Performance is as fast as you can make it and there are less characters to transfer over the wire.

Community's user avatar

answered Aug 24, 2013 at 13:52

Sam Soffes's user avatar

Sam Soffes

15k9 gold badges78 silver badges81 bronze badges

1 Comment

Is there an advantage besides human readability to using ISO 8601 instead of an integer timestamp?

5

I should note that last time I checked Apples NSDate methods didn't support ISO8601. I still have a bug with Apple about putting official support in.

+ (id)dateWithNaturalLanguageString:(NSString *)string

will properly (last time I ran it) parse and create an NSDate object from an ISO801 string, though the documentation says you shouldn't use it, it's worked on all ISO8601 dates I've tried so far.

Jakub's user avatar

Jakub

13.9k17 gold badges84 silver badges143 bronze badges

answered Feb 5, 2010 at 4:06

Colin Wheeler's user avatar

2 Comments

It's true that ` + (id)dateWithNaturalLanguageString:(NSString *)string` will parse successfully unless there are millis on your ISO8601 string.

I should add that you should never use this now. At the time I used this it was working, but since then i've moved onto using other api's that reliably work with ISO8601. dateWithNaturalLanguageString works with ISO8601, but only by accident, don't rely on this continuing to work in the future.

3

@danielbeard answer worked for me. However you need to include the timezone otherwise it converts a UTC date into your current timezone which isn't what you want.

- (NSDate *) dateFromISO8601DateString:(NSString *) dateString {
    NSDateFormatter * dateFormatter = [NSDateFormatter new];
    dateFormatter.timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
    [dateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
    NSDate * date = [dateFormatter dateFromString:dateString];
    return date;
}

answered Jul 8, 2014 at 16:15

gngrwzrd's user avatar

gngrwzrd

6,0424 gold badges46 silver badges57 bronze badges

Comments

2

@Thread captain Try this Format : "yyyy-MM-dd'T'HH:mm:ss.SSS"

Swati's user avatar

Swati

2,9287 gold badges48 silver badges90 bronze badges

answered Oct 18, 2015 at 9:00

Andi Utzinger's user avatar

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.