1
votes

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?

2
Assume your week starts from Monday, today is 27 dec, so you want 31Dec as your answer?Anoop Vaidya
Yes, that's right, assuming the currentCalenar is is set to use Monday as the first day of the week. If it is set to use Sunday as the first day of the week, then nextWeek would be 30 Dec.Mike T
StackOverflow: NSCalendar first day of weekJay
@MikeT : I have posted another answer, kindly let me know, if this is again correct or not?Anoop Vaidya

2 Answers

8
votes

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.

0
votes

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