Given an arbitrary date, I need to find the date of the first day of the next week of the month. Note that it is not as simple as adding 7 days to the current date because the last week of the month may be less than 7 days. Here is the code I'm using now:
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* components = [calendar components:NSWeekOfMonthCalendarUnit|NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSDayCalendarUnit fromDate:currentDate];
NSLog(@"week of month: %ld", [components weekOfMonth]);
[components setWeekOfMonth:[components weekOfMonth] + 1];
NSLog(@"new week of month: %ld", [components weekOfMonth]); //week of month is now 2
[components setWeekday:1];
NSDate *nextWeek = [calendar dateFromComponents:components];
As an example, currentDate is set to 2012-10-01. In this example nextWeek is always 2012-10-01. It appears that sending setWeekOfMonth:
does not increment the other date components in the NSDateComponents
object. Do I have the wrong date components configured, or is setWeekOfMonth:
not supposed to work like that?
So.... Let's start with an NSDate
and an NSCalendar
:
NSDate *date = ...;
NSCalendar *cal = [NSCalendar currentCalendar];
Figure out what day of the week that date is:
NSInteger weekdayOfDate = [cal ordinalityOfUnit:NSWeekdayCalendarUnit inUnit:NSWeekCalendarUnit forDate:date];
NSInteger numberOfDaysToStartOfCurrentWeek = weekdayOfDate - 1;
Let's move that date into the next week:
NSDateComponents *oneWeek = [[NSDateComponents alloc] init];
[oneWeek setWeek:1]; // add one week
[oneWeek setDay:-numberOfDaysToStartOfCurrentWeek]; // ... and subtract a couple of days to get the first day of the week
NSDate *startOfNextWeek = [cal dateByAddingComponents:oneWeek toDate:date options:0];
At this point, you have a date that points to the first day of the next week. Now we should verify that it's still in the same month:
NSDateComponents *monthOfNextWeek = [cal components:NSMonthCalendarUnit fromDate:startOfNextWeek];
NSDateComponents *monthOfThisWeek = [cal components:NSMonthCalendarUnit fromDate:date];
if ([monthOfNextWeek month] != [monthOfThisWeek month]) {
// the first day of the next week is not in the same month as the start date
}
When I run this, I get that the start of next week is 30 Dec 2012 (a Sunday, because my calendar's weeks start on Sunday).
If, however, I want the first day of the week to start on Monday, I can preface this code with:
[cal setFirstWeekday:2]; // the first day of the week is the second day (ie, Monday, because Sunday = 1)
If I do this, then the startOfNextWeek
results in 31 Dec 2012.