February 21, 2011

NSDateFormatter woes

NSDateFormatter has some really obscure behavior that I'm sure trips up a lot of people.  A case in point.  I have an app where a date is sent from the server in the format: "yyyy-MM-dd'T'HH:mm:ssZZ". You would expect that the following code would work just fine:

 
NSDateFormatter dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeStyle:NSDateFormatterFullStyle];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZ"];
 
but you would be wrong.  It appears that 
1) for certain locales (say Japan)
2) when the phone is set to 12 hour mode
 
The date formatter ignores the date format and inserts its own localized AM/PM string and date string parsing fail.  Now in Japan, the standard and thus majority of users use a 24 hour clock, so you will only get intermittent reports of errors/bugs which can be quite frustrating.
 
To fix this, instead of solely relying on setDateFormat, you need to set the locale.  In a rather obscure Q&A, Apple recommends "en_US_POSIX" (see: http://developer.apple.com/library/ios/#qa/qa2010/qa1480.html).  
 
NSDateFormatter dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[[[NSLocale alloc]initWithLocaleIdentifier:@"en_US_POSIX"] autorelease]];
[dateFormatter setTimeStyle:NSDateFormatterFullStyle];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZ"];
 
I'm sure there are many apps, particularly ones developed with only an English speaking user in mind that contain this bug.