0

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?

Anoop Vaidya
  • 46,283
  • 15
  • 111
  • 140
YosiFZ
  • 7,792
  • 21
  • 114
  • 221

3 Answers3

1

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.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • it give me the currect firstdat but the second day is wrong, for this week it gave me 26/5/2013 instead of 25/5/2013 – YosiFZ May 24 '13 at 18:07
  • @MTA: You are correct, I just noticed that. It actually gives the start of the current week and the start of the next week. I can update the answer if you are interested. – Martin R May 24 '13 at 18:09
  • You want to add `length - 1`, not `length`. – rmaddy May 24 '13 at 18:10
  • yes it will be great, but i have another problem that in some methods i need the second day of the week and the third.... How should i implement this for the 4.3 users too? – YosiFZ May 24 '13 at 18:11
  • @MTA: I have updated the answer. The new code can easily be modified to add 2 or 3 days to the first day. – Martin R May 24 '13 at 18:18
0

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.

Tommy
  • 99,986
  • 12
  • 185
  • 204
  • But the question is about why the otherwise perfectly working code only gives the wrong result under iOS 4.3. – rmaddy May 24 '13 at 17:34
  • See my answer; 1 is indeed always Sunday, but Sunday doesn't necessarily start the week, which will make @MTA 's code return bad results. – Mike May 24 '13 at 18:05
  • @rmaddy the question doesn't explain what the author thinks is wrong with the 4.3 result; a suggestion that the author may be confused about what the result should be therefore may be helpful. It felt more useful to try to help. – Tommy May 24 '13 at 19:48
  • @Mike my example is incorrect but per the documentation 'For example, in the Gregorian calendar, n is 7 and Sunday is represented by 1.' That would appear explicitly to say that Sunday is not always 1. NSLocale documents ten different supported calendars (as 'ISO78601 ... is not yet implemented'), and some Googling suggests that all are in active modern use. – Tommy May 24 '13 at 19:53
  • @Tommy I tested it myself. The posted code works perfectly under iOS 5.0 and later. But under iOS 4.3, the results give the values mentioned by the OP in his comment below the question. – rmaddy May 24 '13 at 20:02
0

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.

Mike
  • 1,112
  • 1
  • 13
  • 20
  • Simply removing `NSWeekOfYearCalendarUnit` doesn't fix the issue under iOS 4.3. – rmaddy May 24 '13 at 18:09
  • What about replacing it with NSWeekCalendarUnit? – Mike May 24 '13 at 18:12
  • Also, FWIW, there is a good solution to this problem here: http://stackoverflow.com/questions/11565018/dynamically-create-date-for-last-sunday-at-1200-am/11565353?noredirect=1#comment24040353_11565353 – Mike May 24 '13 at 18:14