14
   NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
   dateFormatter.locale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"] autorelease];
   [dateFormatter setDateFormat:@"EEE, d MMM yyyy HH:mm:ss zzz"];
   NSString *dateString = @"Tue, 08 Jun 2010 17:00:00 EDT";
   NSDate *eventDate = [dateFormatter dateFromString:dateString];

In this case the eventDate object is nil. Can somebody clue me in? This code used to work.

UPDATE: Can't talk about why this doesn't work due to NDA. Suffice it to say, when iOS 4 is out I will post the answer to my own question.

Thom Mahoney
  • 481
  • 1
  • 3
  • 12
  • Are you using "NSString dateString" and "NSDate eventDate" or did you mean "NSString *dateString" and "NSDate *eventDate"? – Dre Jun 07 '10 at 22:20
  • Good catch... This is not the actual code copied verbatim. I didn't want to give too much context on the app. – Thom Mahoney Jun 07 '10 at 22:33
  • i think you should write dd instead of d in setDateFormat , try it . – harshalb Jun 08 '10 at 07:03

5 Answers5

64
/*
    x           number
    xx          two digit number
    xxx         abbreviated name
    xxxx        full name

    a           AM/PM
    A           millisecond of day
    c           day of week (c,cc,ccc,cccc)
    d           day of month
    e           day of week (e,EEE,EEEE)
    F           week of month
    g           julian day (since 1/1/4713 BC)
    G           era designator (G=GGG,GGGG)
    h           hour (1-12, zero padded)
    H           hour (0-23, zero padded)
    L           month of year (L,LL,LLL,LLLL)
    m           minute of hour (0-59, zero padded)
    M           month of year (M,MM,MMM,MMMM)
    Q           quarter of year (Q,QQ,QQQ,QQQQ)
    s           seconds of minute (0-59, zero padded)
    S           fraction of second
    u           zero padded year
    v           general timezone (v=vvv,vvvv)
    w           week of year (0-53, zero padded)
    y           year (y,yy,yyyy)
    z           specific timezone (z=zzz,zzzz)
    Z           timezone offset +0000

    sql         y-M-d H:m:s
    rss         [E, ]d MMM y[y] H:m:s Z|z[zzz]
*/

This is my comment for date parsing. I use the following, where toDateUsingFormat uses an NSDateFormatter with the passed in string. I do not use a locale, because rss dates are not localized.

    if ( 0 == [string rangeOfString:@","].length ) {
        result = [string toDateUsingFormat:@"d MMM y H:m:s z"];
    } else {
        result = [string toDateUsingFormat:@"E, d MMM y H:m:s z"];
    }

Edit:

I use getObjectValue: instead of dateFromString.

NSDate *result = nil;
NSError *error = nil;
[dataFormatter getObjectValue:&result forString:dateString errorDescription:&error];
KlimczakM
  • 12,576
  • 11
  • 64
  • 83
drawnonward
  • 53,459
  • 16
  • 107
  • 112
  • Using a single E didn't work. I will try the one you have for RSS since it is coming from an RSS feed. – Thom Mahoney Jun 07 '10 at 22:40
  • Yeah that didn't work either... I think it might be something broken in the iOS 4 Beta. The reason this is so frustrating is that it used to work just fine! Protected by NDA though so I guess that's all for now. – Thom Mahoney Jun 07 '10 at 22:50
  • I get the following error message with that: "The operation couldn’t be completed. (Cocoa error 2048.)" – Thom Mahoney Jun 07 '10 at 23:06
4

The answer to this question is the following: I was using the wrong date format string:

@"EEE, d MMM yyyy HH:mm:ss zzz"

when it should have been:

@"EEE, dd MMM y HH:mm:ss zzz"

The part about iOS 4 and NDA was that I thought I had to use the NSDateFormatter method dateFormatFromTemplate:options:locale: which would have looked like this:

NSString *format = [NSDateFormatter dateFormatFromTemplate:@"EEE, d MMM yyyy HH:mm:ss zzz" options:0 locale:[NSLocale currentLocale]];

However, that method should only be used when you want to DISPLAY the date to a user of unknown locale. In my case, I knew exactly what the date format was going to look like and I was trying to PARSE the date string so that I could store it in CoreData. Therefore, that method wasn't useful.

Bonus bookmark: Read this table very carefully and you will definitely figure out what the problem is... Unicode date formats should follow these specifications: http://unicode.org/reports/tr35/tr35-6.html#Date_Field_Symbol_Table

TL;DR The format string was wrong. D'oh!

Thom Mahoney
  • 481
  • 1
  • 3
  • 12
3

The full list of format specifiers is UTS#35 Date Format Patterns.

Does the 'c' character work in place of 'E'? The document has it as a very close alternative and it may produce the result you want.

(If you really want characters in the format string that are not in the table you can escape them, like hh 'o''clock' a, zzzz - produces format like "12 o'clock PM, Pacific Daylight Time".)

Adam Eberbach
  • 12,309
  • 6
  • 62
  • 114
0

you have a zero padded day, namely 08 in your date string, however in your format string the format is trying to parse a non-zero padded day, namely d. changing d to dd should fix the problem

akaralar
  • 1,103
  • 1
  • 10
  • 29
0

The problem that I found is that the string that I was parsing has some trailing characters "\n\t\t". The solution was to remove them:

[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

JBK
  • 225
  • 3
  • 8
  • Unfortunately this isn't the problem in the code for the question. As you can see there, the date is hard-coded for the example's sake. Your solution might help some people though! – Thom Mahoney Jul 25 '10 at 03:11