views:

1598

answers:

6

I use a NSDateFormatter which works fine in the simulator, but I get a nil when I run it in the iPhone. I hardcoded the date to be sure of the format, but it fails anyway.

NSString *strPubDate = @"Fri, 8 May 2009 08:08:35 GMT";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[dateFormatter setDateFormat:@"EEE, d MMM yyyy HH:mm:ss Z"];

NSDate *myDate = [dateFormatter dateFromString:strPubDate];

I tried with different region settings, languages etc. on the iPhone. Any idea what is going wrong?

+2  A: 

If you need to use a specific date format you might want to parse it "by hand" rather than using NSDateFormatter. Its behaviour does change depending on the locale, etc. and there are some bugs particularly when you have a timezone in your string.

Having said that, one option in finding what the problem is might be to use the getObjectValue:forString:range:error: method instead of dateFromString:. This way you get an NSError object that (in theory) would tell you what the problem is.

BTW, you don't need the NSDateFormatterBehavior10_4 line. iPhone OS only supports the 10.4+ options, though you won't get any errors if you use the "old" style in the Simulator.

Stephen Darlington
I tried `getObjectValue:forString:range:error:` and got an `Error Domain=NSCocoaErrorDomain Code=2048 "Formatting error."` which is not very meaningful to me. SO I am parsing it by hand, it seems to be the more secure way to do it.Thanks for your answer
Manuel Spuhler
+1  A: 

Nothing stands out, but to help debug this you could try feeding NSDateFormatter a date object and seeing if the resulting string has any minor differences from the one you're trying to parse.

Marc Charbonneau
A: 

When I've parsed a date string with "GMT" at the end, I've used the "zzz" format, not "Z".

Chris Lundie
Thanks, I also tried zzz, but it didn't changed the behavior
Manuel Spuhler
It was zzzz ;-)
Manuel Spuhler
A: 

I second Manuel Spuhler's advice of manually parsing - not my favorite option, but Objective-C's options for that are way too complicated (and lacking in error reporting - anything wrong just spits nil, without a hint on the error).

One thing that worked for me is to use C's strptime to decouple the date, then reconstruct it as a NSDate object. For example, the code below tkes a string received as something like "Monday, 28-Sep-09 18:13:50 UTC" and converts it to a NSDate object adapting the UTC time for the local time:

    struct tm time;
    strptime([currentStringValue UTF8String], "%A, %d-%b-%y %H:%M:%S %z", &time); 
    NSDate* myDate = [NSDate dateWithString:
     [NSString stringWithFormat:@"%04d-%02d-%02d %02d:%02d:%02d +0000",
      time.tm_year+1900, time.tm_mon+1, time.tm_mday,
      time.tm_hour, time.tm_min, time.tm_sec]
    ];

(could handle other zones by adding other struct tm parameters instead of the +0000 fixed time zone, see time.h entry on wikipedia for details):

chester
+4  A: 

This code seems to work correctly against the "GMT" tag.

NSString *strPubDate = @"Fri, 8 May 2009 08:08:35 GMT";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"EEE, d MMM yyyy HH:mm:ss zzzz"];
NSDate *myDate = [dateFormatter dateFromString:strPubDate];

RFC822 Date and Time specs use a few "zone" tags and I found the correct symbol to parse the "GMT" tag Format String for the iPhone NSDateFormatter

  • z~zzz: (Specific GMT Timezone Abbreviation)
  • zzzz: (Specific GMT Timezone Name)
  • Z: +0000 (RFC 822 Timezone

Thanks for all your help!

Manuel Spuhler
A: 

strptime rescued me aswell.

struct tm time;
if (strptime([modDateString UTF8String], "%A, %d %b %Y %H:%M:%S", &time)) {
            NSString *rDate=[NSString stringWithFormat:@"%04d-%02d-%02d %02d:%02d:%02d +0000",
                             time.tm_year+1900, time.tm_mon+1, time.tm_mday,
                             time.tm_hour, time.tm_min, time.tm_sec];

This code works with HTTP dates like Thu, 15 Apr 2010 13:53:56 GMT and Fri, 8 May 2009 08:08:35 GMT which was the original question

StrefanA