17

I want to apologize ahead of time for asking a repeat question, but none of the other solutions have worked for me yet. Every time I try to pass a date string to the dateFromString function I get nil. I haven't read anywhere that things have changed since the iOS 7 update, but I am current on updates if that makes a difference on whether or not this still works the same way.

This is the code I'm using to create the date from string:

    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setTimeZone:[NSTimeZone systemTimeZone]];
    [dateFormat setLocale:[NSLocale systemLocale]];
    [dateFormat setDateFormat:@"yyyy-MM-dd hh:mm:ss"];
    [dateFormat setFormatterBehavior:NSDateFormatterBehaviorDefault];

    NSDate *date = [[NSDate alloc] init];
    date = [dateFormat dateFromString:dateString];

    return date;

I've set up my dateFormat based on all the solutions I've read to solve this problem, but none of these settings have solved by problem. The systemLocale is definitely set up for English so that should not be causing any issues.

This is the dateString I'm passing to dateFromString:

Wednesday, October 9, 2013 at 2:40:29 PM Pacific Daylight Time

Thanks for the help!

Macros185
  • 231
  • 1
  • 3
  • 9
  • You didn't understand what really you need to put in DateFormat... Whith what you put, the dateString should be for example: 2013-01-04 10:32:01. Not what yours looks like. – Larme Oct 10 '13 at 15:42

7 Answers7

42

There are two issues here:

  1. The format of date string the formatter is expecting (@"yyyy-MM-dd hh:mm:ss") is different from the format of the date string you're trying to parse (@"EEEE, MMMM d, yyyy 'at' h:mm:ss a zzzz").

  2. Setting the formatter's locale to [NSLocale systemLocale] is causing [dateFormat dateFromString:] to return nil. Set it to [NSLocate currentLocale].

The full code for the formatter should be:

    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setTimeZone:[NSTimeZone systemTimeZone]];
    [dateFormat setLocale:[NSLocale currentLocale]];
    [dateFormat setDateFormat:@"EEEE, MMMM d, yyyy 'at' h:mm:ss a zzzz"];
    [dateFormat setFormatterBehavior:NSDateFormatterBehaviorDefault];

    NSDate *date = [dateFormat dateFromString:dateString];
Olie
  • 24,597
  • 18
  • 99
  • 131
neilco
  • 7,964
  • 2
  • 36
  • 41
  • Wow, that was it! I'm new to this whole dateFromString business in Objective C. It was easier with stringFromDate because it already knew what was what so I didn't have to do any matching of format strings like you did here. Thanks a lot for the help! – Macros185 Oct 10 '13 at 15:57
  • 3
    @Macros185 No worries. In case you may need it in the future here's [a reference for the date format symbols](http://www.unicode.org/reports/tr35/tr35-25.html#Date_Field_Symbol_Table). Also, if you would kindly click the little up-arrow above the zero next to my answer, I'd appreciate it :) – neilco Oct 10 '13 at 16:01
  • 1
    I would've gladly up-voted this, but my rep doesn't allow me to rate this up yet. Sorry... – Macros185 Oct 10 '13 at 16:20
  • Hmmm, I had so much hope for this! My date string is `2016-03-14 13:41:47`, my dateFormat is `yyyy-MM-dd hh:mm:ss`, my time zone & locale are set, but still `dateFromString:` returns nil. :( – Olie Mar 06 '16 at 22:16
  • 4
    @olie Use `yyyy-MM-dd HH:mm:ss` since your time is using the 24-hour clock. If you want 1am to be `1:00`, use `H:mm`. If you want it zero-padded i.e. 01:00, use `HH:mm`. – neilco Mar 07 '16 at 17:41
  • Heh, thanks. I had *just* discovered that and was coming back to answer my own Q when I saw your comment. If there's no objection, I'm going to make another "official" answer, too. – Olie Mar 07 '16 at 22:07
  • @neilco thanks, in iOS9 and lower versions it works without setLocale and now in iOS10 it returns nil if I didn't set the local, why? and what should I do if don't want use local at all (I'm compering dates from the server and from the device) – Developeder Dec 20 '16 at 14:19
  • Just for others if face problems, for "2017-04-25 18:30:00 +0000" the date format will be - yyyy-MM-dd HH:mm:ss z – Dilip Lilaramani May 18 '17 at 10:27
  • Thanks, I always for get the setDateFormat: ICU date format string for informing the formatter what format of date string is coming with dateFromString: – uchuugaka Jun 21 '20 at 15:09
28

Yet another way to get nil is if you use hh and your hours are on the 24 hr clock and > 12, in that case, you need HH (or H, for zero-padded).

That is:

  • Format: yyyy-MM-DD hh:mm:ss, string: "2016-03-01 13:42:17" will return nil
  • Format: yyyy-MM-DD HH:mm:ss, string: "2016-03-01 13:42:17" will return the date you expect.

Hat-tip to @neilco (see comments below his answer) for this. If you like this answer, please up-vote his, too.

Olie
  • 24,597
  • 18
  • 99
  • 131
5

According to NSDateFormatter documentation :

When working with fixed format dates, such as RFC 3339, you set the dateFormat property to specify a format string.

If your date format is 2017-06-16T17:18:59.082083Z then dateFormat property should look like this yyyy-MM-dd'T'HH:mm:ss.SSSSSSZ.

Swift 3

let dateFormatter = DateFormatter()
let date = "2017-06-16T17:18:59.082083Z"
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSZ"

let result = dateFormatter.date(from: date) // 2017-06-16 17:18:59 +0000
Chris Tsitsaris
  • 590
  • 10
  • 12
  • 1
    You are a life saver, thank you so much! I was using ```yyyy-MM-dd'T'HH:mm:ss.ZZZZZ``` format and it kept returning ```null```. Then I tried your format string and it worked perfectly. I can't believe using ```ss.ZZZZZ``` doesn't work, but using ```ss.SSSSSSZ``` does work..... :/ – Supertecnoboff Jul 17 '17 at 09:37
  • 1
    @Supertecnoboff I had the same issue once, glad it worked! – Chris Tsitsaris Jul 17 '17 at 11:08
  • Interesting that this no longer seems to work. At present (Swift 5.1.3) `result` comes back as `nil`. – Steven W. Klassen Feb 28 '20 at 16:39
2

Your date format doesn't match the string that you're passing, your dateString should be in this formate as per your [dateFormat setDateFormat:@"yyyy-MM-dd hh:mm:ss"];

2013-10-09 02:40:29

nil means dateFormat object was unable to parse your string.

ManicMonkOnMac
  • 1,476
  • 13
  • 21
1

In case anybody is stuck on the same hilarious edge case as me:

"2020-03-08T02:00:00" will return nil as long as you're in a locale that follows Daylight Savings Time, because that hour is skipped and simply doesn't exist.

Elliot Fiske
  • 1,158
  • 8
  • 15
0

You're trying to use dateFromString but the Format you have passed to your Formatter is different of what you're using in dateString.

Try to use this config in your dateFormat: E',' M d',' yyyy 'at' hh:mm:ss aa z

Davi Stuart
  • 269
  • 3
  • 16
0

Don't forget to escape "yyyy/MM/dd' 'HH:mm:ss" space symbols

Henadzi Rabkin
  • 6,834
  • 3
  • 32
  • 39