Sean Michael Dorian
Sean Michael Dorian

Reputation: 397

NSDateFormatter Returns Nil with Seemingly Correct Format String

I'm using an NSDateFormatter to generate NSDate objects from server time strings. We're using ISO-8601 Extended, and below is a method I have that returns a date formatter that handles the transformation:

+ (NSDateFormatter *) dateFormatter {
    NSDateFormatter * dateFormatter = [NSDateFormatter new];
    dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss.SSSZ";
    dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier: @"en_US_POSIX"];
    return dateFormatter;
}

However, when I use that code, the below assert fails:

NSDateFormatter * dateFormatter = [MyClass dateFormatter]; 
                                            //    "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
_testDateObject = [dateFormatter dateFromString: @"2016-01-18'T'16:31:16.401Z"];
NSParameterAssert(_testDateObject);

What's wrong with the date formatting string that I'm using? I've tried variations on it (such as escaping the literals), and none of them produce a valid NSDate.

EDIT My original post included the incorrect formatting string I was using. As pointed out by rmaddy, I should be using yyyy-MM-dd'T'HH:mm:ss.SSSZ, which I am.

Upvotes: 0

Views: 312

Answers (1)

rob mayoff
rob mayoff

Reputation: 386038

Your problem is that your input string, "2016-01-18'T'16:31:16.401Z", doesn't match your format.

In a format string, the ' character begins and ends an escaped sequence of characters. The format substring 'T' matches the input substring T, not the input substring 'T'. Since nothing in your format string matches the single quotes in your input, the conversion fails.

If you really want your input to contain single quotes, you must use doubled single quotes in your format to match them, and use single quotes to escape the T:

let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd'''T'''HH:mm:ss.SSSZ"
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")

let date = formatter.dateFromString("2016-01-18'T'16:31:16.401Z")

// Result:
"Jan 18, 2016, 10:31 AM"

Upvotes: 2

Related Questions