如何计算给定年份 Objective-C 中的日历周数。
我试过:
[calendar rangeOfUnit:NSWeekOfYearCalendarUnit inUnit: NSYearCalendarUnit forDate: [NSDate date]].length
但它返回 54。
谢谢
如何计算给定年份 Objective-C 中的日历周数。
我试过:
[calendar rangeOfUnit:NSWeekOfYearCalendarUnit inUnit: NSYearCalendarUnit forDate: [NSDate date]].length
但它返回 54。
谢谢
您正在使用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
最后,请注意,两者NSWeekOfYearCalendarUnit
都是NSYearForWeekOfYearCalendarUnit
iOS 5.0 和 OS X 10.7。
编辑
正如@lnafziger 所指出的,如果您使用上一年或明年的日历周内的日期,例如 2016 年 1 月 1 日,这将计算该年的周数(示例中为 2015 年),并且不是日期的实际年份(示例中为 2016 年)。如果这不是您想要的,您可以更改日期,如下所示:
NSDateComponents *components = [calendar components:NSYearCalendarUnit fromDate:date];
components.month = 3;
date = [calendar dateFromComponents:components];
经过大量测试后,这里有一个函数可以返回任何年份:
- (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 年开始)对其进行了测试,所有案例都符合规范。