Search code examples
iosobjective-ctimensdatenscalendar

Calculating certain NSDates from days of weeks/weeks of years


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


Solution

  • 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);
    }