views:

68

answers:

2

Hey everybody,

My question is the REVERSE of the typical "How do I find out if an NSDate is between startDate and endDate?"

What I want to do is find ALL NSDATES (to the day, not hour or minute) that occur BETWEEN startDate and endDate. Inclusive of those dates would be preferable, although not necessary.

Example: (I know that these don't represent NSDates, these are just for illustration)

INPUT: startDate = 6/23/10 20:11:30 endDate = 6/27/10 02:15:00

OUTPUT: NSArray of: 6/23/10, 6/24/10, 6/25/10, 6/26/10, 6/27/10

I don't mind doing the work. It's just that I don't know where to start in terms of making efficient code, without having to step through the NSDates little by little.

+3  A: 

Use an NSCalendar instance to convert your start NSDate instance into an NSDateComponents instance, add 1 day to the NSDateComponents and use the NSCalendar to convert that back to an NSDate instance. Repeat the last two steps until you reach your end date.

Johan Kool
This also works, but is a bit messier than drawnonward's solution.
Jus' Wondrin'
Messier? Nope. More correct? Yes. Drawnonward's solution doesn't take into account any issues that may pop up due to calendar peculiarities, such as daylight saving time etc. Using `NSCalendar` certainly is the Apple recommended way.
Johan Kool
NSCalendar is overkill for sequential days. Having the start date at noon covers daylight savings. The fact that days may be a second off 24 hours will not matter until you iterate through 30000 leap seconds and there have only ever been 24. Leap days are 24 hours. Using NSCalendar adds unnecessary complication to a simple task.
drawnonward
Well, in this case you may be able to get away with it, but in general it is a bad habit to forego the NSCalendar route.
Johan Kool
+1  A: 

Add 24 hours to the start date until you go past the end date.

for ( nextDate = startDate ; [nextDate compare:endDate] < 0 ; nextDate = [nextDate addTimeInterval:24*60*60] ) {
  // use date
}

You could round the first date to noon or midnight before starting the loop if you care about the time of day.

drawnonward
I used "timeIntervalSinceDate:" instead of "compare:" since timeIntervalSinceDate returns a numeric value, although compare also works. Additionally, "timeIntervalSinceDate" is deprecated, so I used "dateByAddingTimeInterval:"I thought of doing something like this, but didn't know that I could format for loops like this. Thanks!
Jus' Wondrin'