Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSDateFormatter when iPhone set to 12-hour clock

I'm using an NSDateFormatter to format an NSDate to be in the format "HH:mm 'on' dd MMMM YYYY".

This is the code I've written:

[dateFormatter setDateFormat:@"HH:mm 'on' dd MMMM YYYY"];
[dateFormatter setLocale:[NSLocale currentLocale]];

Then I'm updating a label to display "Data from 12:45 on 22 September 2010", using the method stringFromDate.

NSString *timeAndDateUpdated = [[NSString alloc] initWithFormat:@"Data from %@.", [dateFormatter stringFromDate:date]]

The label is updated correctly if the time on the iPhone is set to 24-hour, but if it's set to 12-hour, the label displays "Data from (null)".

Does anyone know how to solve this problem?

Thanks.

like image 935
Tom W Avatar asked Sep 22 '10 18:09

Tom W


2 Answers

I just ran into this too.

It appears that dates are parsed by the NSDateFormatter according to locale, even if you explicitly specify a date format string!

So in this case, the 24-hour clock HH is being ignored and it's trying to parse using the 12-hour clock as set on the device.

The way to fix it is to explicitly override the NSDateFormatter's locale; in this example setting it to en_US_POSIX will force the 24-hour clock to be used when parsing the hour, i.e.

[dateFormatter setDateFormat:@"HH:mm 'on' dd MMMM YYYY"];
[dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease]];
like image 58
Nathan Brown Avatar answered Oct 15 '22 21:10

Nathan Brown


If the date is solely presented to the user (the "on" suggests it is), I wouldn't force a date format. It's much more friendly to use the long/medium/short date and time styles, which behave according to the user's region format:

[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];

[timeFormatter setDateStyle:NSDateFormatterNoStyle];
[timeFormatter setTimeStyle:NSDateFormatterMediumStyle];

NSString * timeAndDate = [NSString stringWithFormat:"%@ on %@",
  [timeFormatter stringFromDate:date],
  [dateFormatter stringFromDate:date]];

Also note that configuring an NSDateFormatter is incredibly expensive (about 10 ms IIRC). It's fine if you're only going to display it once and not update very often, but it makes scrolling a bit slow if you have a date per table cell. I recently made graph-drawing 50x faster by cacheing date formatters...

like image 6
tc. Avatar answered Oct 15 '22 22:10

tc.