3
    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.

Blago
  • 4,697
  • 2
  • 34
  • 29
  • Does this even compile? Check the brackets on the first line. – Sergey Kalinichenko May 16 '12 at 00:57
  • Made some edits adding more context. Nope, it's not nil, I check for this and return right above these lines. – Blago May 16 '12 at 00:58
  • @dasblinkenlight Very smart, does anything that doesn't compile crash? – Blago May 16 '12 at 01:00
  • @Blago: I believe dasblinkenlight was suggesting that this probably isn't actually the code you're using. This code won't compile, and your actual code must compile (since it crashes), therefore they can't be the same. – abarnert May 16 '12 at 01:02
  • 1
    All it takes is a date string that contains no blank. Easy to accomplish if you set your phone to 24-hour mode. – Hot Licks May 16 '12 at 01:06
  • @abarnert I removed a release from the bottom and added an autorelease for conciseness. – Blago May 16 '12 at 01:06
  • 1
    (See http://stackoverflow.com/questions/6613110/what-is-the-best-way-to-deal-with-the-nsdateformater-locale-feature) – Hot Licks May 16 '12 at 01:08
  • @Blago Oh, you'd be surprised, it so does! Of course, it's the old version that crashes, but since some IDEs are set up to run the last successfully compiled code, you might be tricked into thinking that your new code crashes when it does not even compile. Anyway, inserting a missing bracket into the question is probably a good idea. – Sergey Kalinichenko May 16 '12 at 01:11
  • Haha, I'm going to post a "Does anything that doesn't compile ever crash" just so I an give you the ponts. – Blago May 16 '12 at 01:16
  • http://stackoverflow.com/questions/10610838/does-anything-that-doesnt-compile-ever-crash – Blago May 16 '12 at 01:18
  • @dasblinkenlight: I'm willing to bet he's using Xcode. And the Xcode Run family of commands always tries to rebuild, and refuses to start if the build fails. So, while that's true for lots of other IDEs, it's probably not relevant here. Still, clever point. And you're right that it's worth fixing the answer. – abarnert May 16 '12 at 01:31
  • @abarnert And now that the syntax has been corrected, I can upvote the question too :) – Sergey Kalinichenko May 16 '12 at 01:32
  • @dasblinkenlight I wasn't sarcastic. I actually like the point you made. Although not the case here it's completely possible that the code that the IDE shows is not the code that's running. I've seen it happen with "stale" nib files in XCode. – Blago May 16 '12 at 01:48

2 Answers2

3

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.

abarnert
  • 354,177
  • 51
  • 601
  • 671
  • https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html#//apple_ref/doc/uid/TP40002369-SW4 is the current link to the docs quoted above (I didn't add this to the answer because Apple dev documentation URLs aren't permanent). – abarnert May 16 '12 at 01:11
  • I'm going to give you one big preliminary hug. I believe the crash originated in Europe. – Blago May 16 '12 at 01:11
  • Either way, you answered the question. Thanks! – Blago May 16 '12 at 01:13
  • The obvious workaround here is to check the size of timeParts and assume that if it's 1 you've got a 24-hour time… but you should look at the question HotLinks linked in a comment to the main question for lots of other solutions you might like better. – abarnert May 16 '12 at 01:26
1

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…)

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215