Thursday, June 13, 2013

NSCalendar minimumDaysInFirstWeek example in Objective C (iOS).

NSCalendar minimumDaysInFirstWeek

Returns the minimum number of days in the first week of the receiver.

- (NSUInteger)minimumDaysInFirstWeek

Return Value of [NSCalendar minimumDaysInFirstWeek]
The minimum number of days in the first week of the receiver

NSCalendar minimumDaysInFirstWeek example.
NSCalendar *calendar = [NSCalendar currentCalendar];
calendar.firstWeekday = 2;
calendar.minimumDaysInFirstWeek = 4;
int n = [calendar rangeOfUnit:NSWeekOfYearCalendarUnit inUnit:NSYearForWeekOfYearCalendarUnit forDate: [NSDate date]].length;
NSLog(@"%d", n); // 52

Example of [NSCalendar minimumDaysInFirstWeek].
There are various parameters that cause this effect. First of all, you did not set a calendar for the date formatter. If you add

[dateFormatterWeekly setCalendar:calendar];
to your code, then the output will be as you expected:

date=20130531, week=2013055, start of week=20130526
date=20130602, week=2013062, start of week=20130602
date=20130603, week=2013062, start of week=20130602
But in your case, the date formatter uses the current calendar, and therefore has separate parameters firstWeekDay and minimumDaysInFirstWeek. These parameters are locale dependent. If I test this on the iOS Simulator with the "Region Format" set to "German -> Germany", then

[[dateFormatterWeekly calendar] firstWeekday]           = 2
[[dateFormatterWeekly calendar] minimumDaysInFirstWeek] = 4
and I assume that you will have similar values, because now I get the same output as you.

Now for the date formatter, the week starts on a Monday, which means that June 2 is in the week starting at May 27. This counts as "week #0" in June, because only one day of this week is in June, but minimumDaysInFirstWeek = 4. The first week in a month that has at least minimumDaysInFirstWeek days, counts as "week #1".

End of NSCalendar minimumDaysInFirstWeek example article.