为什么输出的最后两行相同?
使用NSCalendar计算startTime和endTime之间的差异,发现@"2008-02-28 00: 00:00:00“和”2022-02-28 00: 00:00:00“之间的差异以及”2008-02-29 00: 00:00:00“和@"2022-02-28 00: 00:00:00”之间的差异是相同的。它看起来像是NSCalendar的一个bug,也许是关于leapMonth的?
代码:
- (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发布于 2022-09-20 06:58:25
这是意料之中的。做这些周期计算的方法有很多,而NSCalendar使用的方法却不是您所期望的。
文档简要描述了它所做的工作:
有些操作可能是模棱两可的,计算的行为是特定于日历的,但通常会在较小的组件之前计算较大的组件;例如,在公历中,结果可能是1个月零5天,而不是0个月和35天。
这意味着它将计算出这两个日期之间的年份--首先,然后是几个月,然后是几天,等等。“年数”是你所要求的最大的组成部分。
NSCalendar发现,将14年的时间加到2008-02-28年才能得到2022-02-28年的结果.将14年加到2008-02-29也正是2022-02-28,因为2022不是闰年。请注意,“增加一年”并不等于“增加12个月”或“增加365天”。
要想在本例中出现差异,首先需要计算天数。一个周期为5114天,另一个周期为5113天。
还有几个例子:
如果你计算的是2008-02-28和2022-02-01之间的年份、月、日周期,以及2008-02-29和2022-02-01之间的时间。你不会发现有什么不同,两者都是13年11个月和4天。这是因为在2008-02-29和2008-02-28中加上13年,你就可以得到2021-02-28,然后再加11个月是2022-01-28。4天后是2022-02-01。
但是,如果只计算月和日,则2008-02-28和2022-02-01之间的周期和2008-02-29和2022-02-01之间的周期是不同的。
2008-02-28和2022-02-01期间为167个月零4天.截至2008-02至28年度的167个月是2022-01-28.4天后是2022-02-01。
2008-02-29和2022-02-01期间为167个月,为3日.截至2008-02至29年度的167个月是2022-01-29.三天后是2022-02-01。
周期计算很奇怪,不是吗!但它们是以一种独特的方式一致的。
https://stackoverflow.com/questions/73782022
复制相似问题