每年的日历周数(ISO 8601定义)

时间:2012-03-13 22:55:11

标签: objective-c ios ios5 nscalendar

如何计算给定年份的Objective-C中的日历周数。

我试过了:

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

但它返回54.

由于

2 个答案:

答案 0 :(得分:3)

您使用的是NSWeekOfYearCalendarUnit,因此您必须使用相应的较大单位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

最后请注意,NSWeekOfYearCalendarUnitNSYearForWeekOfYearCalendarUnit都只是iOS 5.0和OS X 10.7。

修改

如@lnafziger所述,如果您使用上一年或明年(例如2016年1月)的日历周中的日期,则会计算该年度的周数(2015年示例) ),而不是日期的实际年份(示例中的2016年)。如果这不是您想要的,您可以更改日期,如下所示:

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

答案 1 :(得分:2)

经过大量测试后,这里有一个函数可以将它返回任何一年:

- (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;
}

基本上,根据规范,总周数与一年中星期四的总数相同,这就是计算的结果。

我已经测试了整个400年周期(从0年和2000年开始)并且所有情况都符合规范。