Objective-C:获取一个日历年的天数

Ale*_*exR 8 cocoa cocoa-touch objective-c nsdate nscalendar

我使用以下NSCalendar方法获取日历年中的天数:

NSRange range = [gregorian rangeOfUnit:NSDayCalendarUnit 
                                inUnit:NSYearCalendarUnit 
                               forDate:date];
Run Code Online (Sandbox Code Playgroud)

我期望range.length返回值类型NSRange为365或366(天).

但是,此代码返回range.length31对的日期值2005-06-06.

我的代码出了什么问题?

这是完整的代码段:

NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];

[subArray enumerateObjectsUsingBlock:
   ^(NSDate *date, NSUInteger idx, BOOL *stop) {
   NSUInteger numberOfDays = [gregorian ordinalityOfUnit:NSDayCalendarUnit
   inUnit:NSYearCalendarUnit forDate:date];
}];
Run Code Online (Sandbox Code Playgroud)

Nik*_*uhe 2

计算给定日期一年中的天数:

NSDate *someDate = [NSDate date];

NSDate *beginningOfYear;
NSTimeInterval lengthOfYear;
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[gregorian rangeOfUnit:NSYearCalendarUnit
             startDate:&beginningOfYear
              interval:&lengthOfYear
               forDate:someDate];
NSDate *nextYear = [beginningOfYear dateByAddingTimeInterval:lengthOfYear];
NSInteger startDay = [gregorian ordinalityOfUnit:NSDayCalendarUnit
                                          inUnit:NSEraCalendarUnit
                                         forDate:beginningOfYear];
NSInteger endDay = [gregorian ordinalityOfUnit:NSDayCalendarUnit
                                        inUnit:NSEraCalendarUnit
                                       forDate:nextYear];
NSInteger daysInYear = endDay - startDay;
Run Code Online (Sandbox Code Playgroud)

遗憾的是:这在 1582 年无法正常工作。

1582 年,Gregor 推出了目前广泛使用的历法,需要进行修复以使太阳历与历年保持一致。所以他们采取了务实的解决方案:他们只是放弃了 10 月 5 日至 14 日。(他们也没有疯狂到改变工作日)。结果1582年只有355天。

附录:上面的代码仅适用于 1582 年之后的年份。例如,即使今年是当时使用的儒略历中的闰年,它也会返回 1500 年的 365 天。公历从 1582 年 10 月 15 日开始。根据公历进行的计算在该日期之前并未定义。所以这样看来苹果的实现是正确的。我不知道 1583 年之前的 Cocoa 上有正确的实现。

  • 它“完全”一致:它使用“proleptic Gregorian calendar”,大致意思是“使用相同的规则重新标记向后工作的日期”。因此 1500 不是闰年,但 1200 是(还有 0000,请不要开始关于 0 年的争​​论)。必须小心避免误解,但这是 ISO 8601 指定的内容、天文学家使用的内容以及历史学家为了使计算更容易而转换的内容(通常带有后缀“NS”)。 (2认同)