Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSDateFormatter crash. How come?

    NSDateFormatter *timeFormatter = [[[NSDateFormatter alloc] init] autorelease];
    [timeFormatter setDateFormat:@"h:mm a"];
    NSString *fullTime = [timeFormatter stringFromDate:someDateHere];
    NSArray *timeParts = [fullTime componentsSeparatedByString:@" "];
    timeLabel.text = [timeParts objectAtIndex:0];
    ampmLabel.text = [timeParts objectAtIndex:1];

The LAST line crashes with

    NSRangeException*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]

How is this possible? There is a nil check on the date that returns just before this code.

like image 362
Blago Avatar asked Mar 05 '26 10:03

Blago


2 Answers

From the Data Formatting Guide documentation (section Date Formatters > Use Format Strings to Specify Custom Formats > Fixed Formats):

Although in principle a format string specifies a fixed format, by default NSDateFormater still takes the user’s preferences (including the locale setting) into account. ... In iOS, the user can override the default AM/PM versus 24-hour time setting. This may cause NSDateFormatter to rewrite the format string you set.

In other words, on an iOS device that's set for 24-hour time setting, you won't get "6:02 PM", you'll get "18:02", even though you specified "h:mm a". So when you separate that by spaces, you get back a single value, "18:02", not two values.

like image 53
abarnert Avatar answered Mar 06 '26 22:03

abarnert


There's a caveat in the documentation for NSDateFormatter that says:

Note that although setting a format string (setDateFormat:) in principle specifies an exact format, in practice it may nevertheless also be overridden by a user’s preferences—see Data Formatting Guide for more details.

Could this apply in your case to produce a string without any spaces in it? (That would lead to a length 1 array when split by spaces, giving the exception you see in the place you see it.) Check this by logging the formatted date or attaching a debugger.

Note that the end of the page on date formats does recommend using plain old strftime_l when dealing with unlocalized dates/times. That might be more suitable for you. (Also, you want an AM/PM indicator in data that's bound for a computer? Seriously? The 24-hour clock is way easier to work with usually…)

like image 28
Donal Fellows Avatar answered Mar 07 '26 00:03

Donal Fellows



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!