I am currently developing an iPad client for a Java-based Web app that uses JAX-RS for the Web interface (Jersey is the implementation of JAX-RS being used).
I ran into an interesting problem yesterday regarding the parsing of RFC 3339 dates (example - 2011-04-28T16:28:03.065-07:00) in iOS. Apple nicely documents how to parse RFC 3339 dates, but leaves out one detail.
There is an issue with the timezone containing the colon ':' character. The character must be removed for the RFC 3339 date to be able to be parsed into an NSDate instance. I spent some time until I found this as a comment in a date parsing class. Removing the colon from the timezone portion (i.e. 2011-04-28T16:28:03.065-0700) allows NSDateFormatter to parse the textual representation of the date into an NSDate instance.
I also ran into a cute issue: sometimes the fractional seconds aren't included, most likely because the value is 0. I had to use two NSDateFormatter instances, one using 'yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSSZ' the other 'yyyy'-'MM'-'dd'T'HH':'mm':'ssZ' for the date without milliseconds.
Here is the final version of the code to parse RFC 3339 date text into an NSDate instance.
NSMutableString* dateString = [rfc3339DateTimeString mutableCopy];
NSRange range = [dateString rangeOfString:@":" options:NSBackwardsSearch];
if (range.location != NSNotFound) {
// remove the last ':'
[dateString deleteCharactersInRange:range];
}
// Convert the RFC 3339 date time string to an NSDate.
static NSDateFormatter* rfc3339DateFormatter1 = nil;
static NSDateFormatter* rfc3339DateFormatter2 = nil;
if (rfc3339DateFormatter1 == nil) {
rfc3339DateFormatter1 = [[NSDateFormatter alloc] init];
NSLocale* enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
[rfc3339DateFormatter1 setLocale:enUSPOSIXLocale];
[rfc3339DateFormatter1 setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSSZ"];
[rfc3339DateFormatter1 setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
rfc3339DateFormatter2 = [[NSDateFormatter alloc] init];
[rfc3339DateFormatter2 setLocale:enUSPOSIXLocale];
[rfc3339DateFormatter2 setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ssZ"];
[rfc3339DateFormatter2 setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[enUSPOSIXLocale release];
}
NSDate* date = [rfc3339DateFormatter1 dateFromString:dateString];
if (date == nil) {
date = [rfc3339DateFormatter2 dateFromString:dateString];
}
return date;
No comments:
Post a Comment