views:

1488

answers:

13

I had the following code working on on OS 3.x

NSString *stringDate = @"2010-06-21T20:06:36+00:00";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
NSDate *theDate = [dateFormatter dateFromString:stringDate];
NSLog(@"%@",[dateFormatter stringFromDate:theDate]);

but now in the newest xcode 3.2.3 under the iOS4 simulator, the varialble theDate is nil.

I have looked through the class reference and do not see anything deprecated or implemented differently for iOS4 with these specific methods. What did i leave out?

A: 

Looks fine to me.

Does it still function correctly on a real device?

If so file a bug report for the simulator, otherwise file a bug report for iOS 4.

Ben S
i cant test on a device yet, mine is messed up right now. I was hoping it was just a simulator problem but the dateformatter just didnt seem to be something that the simulator would have an issue with.
AtomRiot
ok, just tried this code on a device and i see the same behavior as the simulator. :(
AtomRiot
+1  A: 

Is your device set to 24 hour or 12 hour clock?

That sounds like an insane question but I've just run into that bug - the dateformatter will adjust your format string according to the current locale which will include the time format settings.

You can force it to ignore them by adding this line :

[dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease]];

Hope that helps.

deanWombourne
hmm, i dont see it making any difference. still getting the null value from the dateFromString call.
AtomRiot
In that case, my answer is completely wrong. Sorry!
deanWombourne
This was a bug in the 2.x days. Not sure whether it's still present as I ended up parsing the string "by hand."
Stephen Darlington
It's definitely still present - it's not a bug anymore though, they've documented it __;-)__
deanWombourne
This worked for me. And this Apple link explains all: http://developer.apple.com/iphone/library/qa/qa2010/qa1480.html
Kris Jenkins
A: 

You use dataFormat @"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z"

mshiro
+1  A: 

I ran into this issue recently. I ended up using Peter Hosey's ISO8601 parser. It is available here: http://boredzo.org/iso8601unparser/

Elfred
This saved my life, thanks. I prefer using a specific parser than tinkering with the input date string.
Luzal
A: 

My previous answer is wrong. Sorry! I get the value from dataFormat @"yyyy'-'MM'-'dd'T'HH':'mm':'ss'+'hh:mm";

mshiro
Everything up to the timezone was not giving me any troubles. It was just the timezone part. And I am getting timezone data so i had to alter the input a little before parsing
AtomRiot
A: 

I was just debugging this exact same problem. I have the same date string as you that works in 3.x and not 4.0. Same symptoms.

When looking through the NSDateFormatter documentation I see:

Initializing a Date Formatter – init Available in iPhone OS 2.0 through iPhone OS 3.2

This says that the init method has been deprecated for iOS 4.0. I'm not sure what that means.

Onazuka
I also saw that when reading through the class reference but it makes no other mention of what it means. And Xcode does not mark it as depricated.
AtomRiot
A: 

The link Elfred posted did the trick. I stumbled upon the same issue whilst converting my app from 3.1.3 to iOS4. The link holds the ISO8601DateFormatter class which is a far more excellent extension then my own date utility class.

Elfred wrote: I ran into this issue recently. I ended up using Peter Hosey's ISO8601 parser. It is available here: http://boredzo.org/iso8601unparser/

+1  A: 

The format that I am being given is halfway between RFC 822 and GMT. if i change the "+00:00" to "+0000" then I can use the "Z" on my format. and if i change it to "GMT+00:00" then I can use ZZZZ to get the data properly. It seems that something has been stripped out to handle this hybrid as it was working for me before with OS 3.x.

AtomRiot
A: 

It seems the NSDateFormatter has gotten very picky.

-(void)dateFormatterTests {
    NSDateFormatter *formatter;

    formatter = [[NSDateFormatter alloc] init];

#ifdef WORKS
    [formatter setDateFormat:@"yyyy-MM-dd"];
#elif defined(ALSO_WORKS)
    [formatter setDateFormat:@"yyyy MM dd"];
    [formatter setLenient:YES];
#else // DOESN'T WORK
    [formatter setDateFormat:@"yyyy MM dd"];
#endif

    // Works per comments above
    NSLog(@"dFS: %@", [formatter dateFromString:@"2010-01-13"]);  
    // Never works with any of the above formats
    NSLog(@"dFS: %@", [formatter dateFromString:@"2010-01-13 22:00"]); 

    [formatter release]; formatter = nil;
}
John Franklin
This code does not take into account the time zone. I am being given the time zone in a specific format and i cannot change that.
AtomRiot
I'm sorry. That point of the post was to show there formatter would return nil in cases where you'd think it should produce something, such as when decoding only a date, but also adding a time in the string. I'm glad you got it working.
John Franklin
A: 

Hi, I had the same issue in my apps as well Null Value from NSDateFormatter.

I found my problem to be the following:

I was sending my app a date and time like this: 07/16/2010 04:21:00 +00:00 with the formatter like this: [dateFormatter setDateFormat:@"MM/dd/yyyy HH:mm:ss ZZZ"]

It seems like the ZZZ part of the formating NO LONGER accepts the colon : in the time.

Works: 07/16/2010 04:21:00 +0000

Doesn't work: 07/16/2010 04:21:00 +00:00

To support the current apps that are out, all I did was search for the +00:00 part in the string and replace it with +0000.

Hope this might help others.

RoLYroLLs
+1  A: 

This code will remove the extra colon as AtomRiot describes:

Converting it from:

  • NSString *stringDate = @"2010-06-21T20:06:36+00:00";

to

  • NSString *stringDate = @"2010-06-21T20:06:36+0000";

    // Remove colon in timezone as iOS 4+ NSDateFormatter breaks

        if (stringDate.length > 20) {
            stringDate = [stringDate stringByReplacingOccurrencesOfString:@":"
                                                                     withString:@""
                                                                        options:0
                                                                          range:NSMakeRange(20, stringDate.length-20)];
        }
    

for more details see: https://devforums.apple.com/thread/45837

Benjamin Ortuzar
Thank you very much...
Sijo
A: 

I found out it works if you do it this way (see below). The key is using the method: - [NSDateFormatter getObjectValue:forString:range:error:]

instead of

-[NSDateFormatter dateFromString]

The complete code:

+ (NSDate *)parseRFC3339Date:(NSString *)dateString {
     NSDateFormatter *rfc3339TimestampFormatterWithTimeZone = [[NSDateFormatter alloc] init];
     [rfc3339TimestampFormatterWithTimeZone setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease]];
     [rfc3339TimestampFormatterWithTimeZone setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
     NSDate *theDate = nil;
     NSError *error = nil; 
     if (![rfc3339TimestampFormatterWithTimeZone getObjectValue:&theDate forString:dateString range:nil error:&error]) {
      NSLog(@"Date '%@' could not be parsed: %@", dateString, error);
     }
     return theDate;
    }
Werner Altewischer