views:

848

answers:

4

For example I have

NSDate *curDate = [NSDate date];

and its value is 9:13 am. I am not using year, month and day parts of curDate.

What I want to get is date with 9:15 time value; If I have time value 9:16 I want to advance it to 9:20 and so on.

How can I do that with NSDate?

thx

+4  A: 

Take the minute value, divide by 5 rounding up to get the next highest 5 minute unit, multiply to 5 to get that back into in minutes, and construct a new NSDate.

NSDateComponents *time = [[NSCalendar currentCalendar]
                          components:NSHourCalendarUnit | NSMinuteCalendarUnit
                            fromDate:curDate];
NSInteger minutes = [time minute];
float minuteUnit = ceil((float) minutes / 5.0);
minutes = minuteUnit * 5.0;
[time setMinute: minutes];
curDate = [[NSCalendar currentCalendar] dateFromComponents:time];
Dustin Voss
Another option for the rounding itself is: remainder = minutes % 5; if (remainder) minutes += 5 - remainder;
smorgan
+1  A: 

Had been looking for this myself, but using the example above gave me from year 0001 dates.

Here's my alternative, incorporated with smorgan's more elegant mod suggestion though beware I haven't leak tested this yet:

     NSDate *myDate = [NSDate date];
 // Get the nearest 5 minute block
 NSDateComponents *time = [[NSCalendar currentCalendar]
         components:NSHourCalendarUnit | NSMinuteCalendarUnit
         fromDate:myDate];
 NSInteger minutes = [time minute];
 int remain = minutes % 5;
 // Add the remainder of time to the date to round it up evenly
 myDate = [myDate addTimeInterval:60*(5-remain)];
The reason you got year 0001 dates is because the NSCalendar was making the new date from an NSDateComponents that didn't include years. A solution would have been to add more NSCalendarUnits when creating the time variable.
Dustin Voss
Thanks Dustin.. Had learnt more about the NSCalendar usage myself later with the other components
+1  A: 

Thanks for the sample. Below I have added some code the round to nearest 5 minutes

 -(NSDate *)roundDateTo5Minutes:(NSDate *)mydate{
    // Get the nearest 5 minute block
    NSDateComponents *time = [[NSCalendar currentCalendar]
            components:NSHourCalendarUnit | NSMinuteCalendarUnit
            fromDate:mydate];
    NSInteger minutes = [time minute];
    int remain = minutes % 5;
    // if less then 3 then round down
    if (remain<3){
     // Subtract the remainder of time to the date to round it down evenly
     mydate = [mydate addTimeInterval:-60*(remain)];
    }else{
     // Add the remainder of time to the date to round it up evenly
     mydate = [mydate addTimeInterval:60*(5-remain)];
    }
    return mydate;
}
bleeksie
+1  A: 

Here's my solution to the original problem (rounding up) using ayianni's wrapper idea.

-(NSDate *)roundDateToCeiling5Minutes:(NSDate *)mydate{
// Get the nearest 5 minute block
NSDateComponents *time = [[NSCalendar currentCalendar]
    components:NSHourCalendarUnit | NSMinuteCalendarUnit
           fromDate:mydate];
NSInteger minutes = [time minute];
int remain = minutes % 5;
// Add the remainder of time to the date to round it up evenly
mydate = [mydate addTimeInterval:60*(5-remain)];
return mydate;

}

treblig