You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

是否为NSCalendar的Bug?为何两组日期差计算结果一致?

NSCalendar计算闰日日期差的异常表现

使用NSCalendar计算起始时间与结束时间的差值时,发现2008-02-28 00:00:00到2022-02-28 00:00:00和2008-02-29 00:00:00到2022-02-28 00:00:00的差值完全相同,疑似和闰日处理有关。

测试代码

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self printDiffBetweenStartTime:@"2008-02-27 00:00:00" endTime:@"2022-02-28 00:00:00"];
    [self printDiffBetweenStartTime:@"2008-02-28 00:00:00" endTime:@"2022-02-28 00:00:00"];
    [self printDiffBetweenStartTime:@"2008-02-29 00:00:00" endTime:@"2022-02-28 00:00:00"];
}

- (void)printDiffBetweenStartTime:(NSString *)startTime endTime:(NSString *)endTime
{
    static NSDateFormatter *dateFormatter;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        dateFormatter = [[NSDateFormatter alloc] init];
        dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
        dateFormatter.calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
    });
    
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDate *startDate = [dateFormatter dateFromString:startTime];
    NSDate *endDate = [dateFormatter dateFromString:endTime];
    
    NSCalendarUnit unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
    NSDateComponents *components = [calendar components:unitFlags fromDate:startDate toDate:endDate options:0];
    NSLog(@"\"%@\" to \"%@\" : %@ year %@ month %@ day %@ hour %@ minute %@ second", startTime, endTime, @(components.year), @(components.month), @(components.day), @(components.hour), @(components.minute), @(components.second));

}

输出结果

"2008-02-27 00:00:00" to "2022-02-28 00:00:00" : 14 year 0 month 1 day 0 hour 0 minute 0 second
"2008-02-28 00:00:00" to "2022-02-28 00:00:00" : 14 year 0 month 0 day 0 hour 0 minute 0 second
"2008-02-29 00:00:00" to "2022-02-28 00:00:00" : 14 year 0 month 0 day 0 hour 0 minute 0 second

原因说明

这并不是NSCalendar的Bug,而是日历系统处理闰日的常规逻辑:2022年不是闰年,2月没有29日,当计算以闰日(2008-02-29)为起点的日期差时,NSCalendar会自动将每年对应的日期调整为当年2月的最后一天。2022年的2月最后一天是28日,所以从2008-02-29到2022-02-28刚好是完整的14年周期,天数差为0,和2008-02-28到2022-02-28的差值一致。

内容的提问来源于stack exchange,提问作者Sheldon Hu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 22:45:36