Question

I'm trying to get an NSMutableArray of NSDates each NSDate object targets the nearest rounded either HH:00 or HH:30 for the next 24 hours from now.

lets say right now its 02:31 I want an output of @[03:00,03:30,04:00,04:30...03:00(of the next day)]

if its 02:29 then I want @[02:30,03:00 and so on till the next day at 02:30].

right now I have the code below and it works almost all the time, yet rarely I get an output of all the NSDate objects that I want with a remainder of an extra minute(@[03:01,03:31:04:01...so on]).

any ideas ?

-(NSMutableArray*)TwentyFourHoursFromNowDivicedBy30Mins
{

    NSMutableArray * dateArray = [NSMutableArray array];
    NSCalendar * cal = [NSCalendar currentCalendar];

    NSDateComponents * plusDays = [NSDateComponents new];
    NSDate * now = [self changeTimeValue:[NSDate date]];

    for( NSUInteger day = 0; day < 2; day++ )
    {
        [plusDays setDay:day];
        [dateArray addObject:[cal dateByAddingComponents:plusDays toDate:now options:0]];
    }

    NSDate *startDate = [dateArray objectAtIndex:0];
    NSDate *endDate = [dateArray objectAtIndex:1];
    NSDateComponents *diff = [[NSDateComponents alloc] init];
    [diff setMinute:0];
    NSCalendar *calz = [NSCalendar currentCalendar];
    NSDate *tmp = startDate;

    NSMutableArray *dates = [NSMutableArray arrayWithObject:tmp];

    while ([tmp laterDate:endDate] == endDate) {
        [diff setMinute:[diff minute] + 30];
        tmp = [calz dateByAddingComponents:diff toDate:startDate options:0];
        [dates addObject:tmp];

    }


    return dates;

}
- (NSDate *)changeTimeValue:(NSDate *)dateValue{
    NSDateComponents *time = [[NSCalendar currentCalendar]
                              components:NSHourCalendarUnit | NSMinuteCalendarUnit
                              fromDate:dateValue];
    long val = 0;
    NSDate *newDate = [[NSDate alloc] init];
    NSInteger minutes = [time minute];
    if(minutes > 0 && minutes < 30) {
        val = 30 - minutes; NSTimeInterval aTimeInterval = [dateValue
                                                            timeIntervalSinceReferenceDate] + 60 * val + minutes;
        newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval];
        return newDate;
    } else if(minutes > 30 && minutes < 60) {
        val = 60 - minutes;
        NSTimeInterval aTimeInterval = [dateValue timeIntervalSinceReferenceDate]
        + 60 * val;
        newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval];
        return newDate;
    } else {
        return newDate;
    }
}
Était-ce utile?

La solution

You're not zeroing out the seconds in your changeTimeValue, and in any case I think you've overcomplicated it. So I suspect you're subsequently seeing rounding issues. Just use NSDateComponents to do the whole job:

NSCalendar *currentCalendar = [NSCalendar currentCalendar];

NSDateComponents *dateComponents = [currentCalendar
                              components:NSHourCalendarUnit | 
                                         NSMinuteCalendarUnit | 
                                         NSYearCalendarUnit |
                                         NSMonthCalendarUnit |
                                         NSDayCalendarUnit
                              fromDate:dateValue];

dateComponents.minute += 15;
dateComponents.minute -= dateComponents.minute%30;

return [currentCalendar dateFromComponents:dateComponents];
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top