问题描述:

Is there an easy way to calculate dates according to a criteria with NSCalendar and/or NSCalendarComponents? I've been looking at the documentation for a while but it seems a bit complicated. For example, I need

"Wednesday 6:00pm"s for the next 15 even-numbered weeks (including this one if it's even numbered and not past that date/time yet.)

网友答案:

Here is a method for determining which Wednesday to start with and then getting the next 14 even week Wednesdays. This doesn't take the time portion of your question into account, but you can use similar methods to handle the time.

+ (NSArray *)nextFifteenEvenNumberedWeekWednesdays:(NSDate *)startingDate
{
    static const NSInteger Wednesday = 4;
    static const NSInteger OneDay = 60 * 60 * 24;
    NSCalendar *calender = [NSCalendar currentCalendar];
    NSDateComponents *startingDateComponents = [calender components:(NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitWeekday | NSCalendarUnitWeekOfYear)
                                                           fromDate:startingDate];

    // Go to the closest Wednesday
    NSInteger daysToWednesday = Wednesday - startingDateComponents.weekday;
    if (startingDateComponents.weekday > Wednesday) {
        // We already passed wednesday, so go to the next wednesday
        if (startingDateComponents.weekOfYear % 2 == 0) {
            // If this date is past Wednesday but is on an even week, then moving to the next wednesday
            // will be an odd week. So skip forward one week.
            startingDate = [startingDate dateByAddingTimeInterval:7 * OneDay];
        }
        daysToWednesday = 7 + daysToWednesday; // get the next Wednesday
    }
    startingDate = [startingDate dateByAddingTimeInterval:daysToWednesday * OneDay]; // Move to wednesday

    NSMutableArray *wednesdays = [NSMutableArray array];
    for (NSInteger i = 0; i < 15; i++) {
        // Add every other wednesday
        [wednesdays addObject:[startingDate dateByAddingTimeInterval:14 * i * OneDay]];
    }

    return [wednesdays copy];
}
网友答案:

I ended up answering my own question. It's really easy when you know -[NSCalendar dateBySettingUnit:value:ofDate:options:] auto-increments forward to the next matching date.

NSCalendar *calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierISO8601];

NSDate *date = [NSDate date];

// find the next Wednesday 6 o'clock
date = [calendar dateBySettingUnit:NSCalendarUnitSecond value:0 ofDate:date options:0];
date = [calendar dateBySettingUnit:NSCalendarUnitMinute value:0 ofDate:date options:0];
date = [calendar dateBySettingUnit:NSCalendarUnitHour value:18 ofDate:date options:0];
date = [calendar dateBySettingUnit:NSCalendarUnitWeekday value:4 ofDate:date options:0];

// skip one week if it's not an even week
NSDateComponents *components = [calendar components:NSCalendarUnitWeekOfYear fromDate:date];
date = [calendar dateByAddingUnit:NSCalendarUnitWeekOfYear value:components.weekOfYear % 2 toDate:date options:0];

// 15 weeks of this
for (int i = 0; i < 15; i++)
{
    NSDate *testDate = [calendar dateByAddingUnit:NSCalendarUnitWeekOfYear value:i * 2 toDate:date options:0];
    NSLog(@"Date: %@", testDate);
}
相关阅读:
Top