Question

I an using the current methods to get the first and the last day of the current week:

NSDate *weekDate = [NSDate date];
NSCalendar *myCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSDateComponents *currentComps = [myCalendar components:( NSYearCalendarUnit | NSMonthCalendarUnit | NSWeekOfYearCalendarUnit | NSWeekdayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit) fromDate:weekDate];

[currentComps setWeekday:1]; // 1: sunday
NSDate *firstDayOfTheWeek = [myCalendar dateFromComponents:currentComps];
[currentComps setWeekday:7]; // 7: saturday
NSDate *lastDayOfTheWeek = [myCalendar dateFromComponents:currentComps];

This was working perfect, but now in ios 4.3 and it's not working.

Any idea what can be the problem?

Was it helpful?

Solution

I have started Xcode 4.1 on my OS X 10.6 partition and tried to compile your code against the iOS 4.3 SDK. It turned out that NSWeekOfYearCalendarUnit is undefined, so that must have been introduced in later iOS versions. This might explain why it does not work on iOS 4.3.

The following alternative code works and gives the correct result:

NSDate *now = [NSDate date];
NSCalendar *myCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSDate *firstDayOfTheWeek;
NSTimeInterval length;
[myCalendar rangeOfUnit:NSWeekCalendarUnit
                                startDate:&firstDayOfTheWeek
                                 interval:&length
                                  forDate:now];
NSDate *lastDayOfTheWeek = [firstDayOfTheWeek dateByAddingTimeInterval:length];

Update: The above code gives the (start of) the first day in the week and the (start of) the next week. If you add (length - 1) instead of length then you will get the end of the last day in the week (thanks @rmaddy!). Alternatively, you can add 6 days to the first day:

NSDate *now = [NSDate date];
NSDate *firstDayOfTheWeek;
NSCalendar *myCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[myCalendar rangeOfUnit:NSWeekCalendarUnit
                                startDate:&firstDayOfTheWeek
                                 interval:NULL
                                  forDate:now];
NSDateComponents *sixDays = [[NSDateComponents alloc] init];
[sixDays setDay:6];
NSDate *lastDayOfTheWeek = [myCalendar dateByAddingComponents:sixDays toDate:firstDayOfTheWeek options:0];

Remark: This code also handles the "start of week" correctly according to the locale.

OTHER TIPS

Your third component, NSWeekOfYearCalendarUnit, is only available as of iOS 5. See https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSCalendar_Class/Reference/NSCalendar.html. I believe for what you are doing, you don't need that component, you should be able to just remove it.

As for the localization comments from the others on this post, they are correct that things change in different locales, but not the way you might expect. Sunday is indeed always day 1 (and Saturday day 7), but in cultures where Monday is the first day of the week, your code will return the following Saturday and the following Sunday, seemingly at the end of the week. You can fix this by explicitly setting your calendar to use the en-US locale, or attempt to account for other locales by using the firstDayOfWeek property. You can test this by switching the Region Format of you simulator to German > Germany, in Settings > General > International > Region Format.

It's unclear in which sense you are having difficulties, but it might be simply that there's no consensus on which is the first day of the week.

[old example redacted; Mike below correctly pointed out that it was invalid]

Per the NSDateComponents documentation, "For example, in the Gregorian calendar, n is 7 and Sunday is represented by 1."; if your device is using any of the nine other calendars supported by iOS — such as the Buddhist, Chinese or Hebrew calendars — then Apple doesn't guarantee that Sunday is day 1.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top