Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

Will this be a valid answer :

NSDateFormatter *dateFormatter=[NSDateFormatter new];
[dateFormatter setLocale:[[NSLocale alloc]initWithLocaleIdentifier:@"en_US_POSIX"]];
[dateFormatter setDateFormat:@"EEE"];

NSDate *date=[NSDate date];
NSString *dateString=[dateFormatter stringFromDate:date];

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
NSDateComponents *components = [NSDateComponents new];

[calendar setFirstWeekday:1];//1 for Mon

NSDate *newDate=date;

while (![dateString isEqualToString:@"Mon"]) {
    components.day = 1;
    newDate = [calendar dateByAddingComponents:components toDate:newDate options:0];
    dateString=[dateFormatter stringFromDate:newDate];
}
NSLog(@"Upcoming week Date=%@",newDate);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top