Question

how can I calculate the number of calendarweeks in objective-C for a given year.

I tried:

[calendar rangeOfUnit:NSWeekOfYearCalendarUnit inUnit: NSYearCalendarUnit forDate: [NSDate date]].length

but it returns 54.

Thanks

Was it helpful?

Solution

You are using NSWeekOfYearCalendarUnit, so you must use the corresponding larger unit which is NSYearForWeekOfYearCalendarUnit.

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

Finally, note that both NSWeekOfYearCalendarUnit and NSYearForWeekOfYearCalendarUnit are iOS 5.0 and OS X 10.7 only.

Edit

As noted by @lnafziger, if you use a date that is in a calendar week from the previous year or next year such as 1/1/2016, this will calculate the number of weeks in that year (2015 in the example), and not the actual year of the date (2016 in the example). If this is not what you want, you can change the date like follows:

NSDateComponents *components = [calendar components:NSYearCalendarUnit fromDate:date];
components.month = 3;
date = [calendar dateFromComponents:components];

OTHER TIPS

After a significant amount of testing, here is a function which will return it for any year:

- (NSUInteger)iso8601WeeksForYear:(NSUInteger)year {
    NSCalendar *calendar = [NSCalendar currentCalendar];

    NSDateComponents *firstThursdayOfYearComponents = [[NSDateComponents alloc] init];
    [firstThursdayOfYearComponents setWeekday:5]; // Thursday
    [firstThursdayOfYearComponents setWeekdayOrdinal:1]; // The first Thursday of the month
    [firstThursdayOfYearComponents setMonth:1]; // January
    [firstThursdayOfYearComponents setYear:year];
    NSDate *firstThursday = [calendar dateFromComponents:firstThursdayOfYearComponents];

    NSDateComponents *lastDayOfYearComponents = [[NSDateComponents alloc] init];
    [lastDayOfYearComponents setDay:31];
    [lastDayOfYearComponents setMonth:12];
    [lastDayOfYearComponents setYear:year];
    NSDate *lastDayOfYear = [calendar dateFromComponents:lastDayOfYearComponents];

    NSDateComponents *result = [calendar components:NSWeekCalendarUnit fromDate:firstThursday toDate:lastDayOfYear options:0];

    return result.week + 1;
}

Basically, per the spec, the total number of weeks is the same as the total number of Thursday's in the year, which is what this calculates.

I have tested it for the entire 400 year cycle (starting in the year 0 and the year 2000) and all cases match the spec.

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