日历:获取日期组件,奇怪的情况

时间:2017-11-10 12:04:04

标签: ios swift date calendar foundation

我试图找出为什么这段代码如此奇怪。您可以在下面找到详细信息:

let nowDate = Date()
let threeDayBeforeNowDate_t1 = Date(timeIntervalSinceNow: -60 * 60 * 24 * 3)
let oneDayAfterNowDate = Date(timeIntervalSinceNow: 60 * 60 * 24 * 1)
let threeDayBeforeNowDate_t2 = Date(timeIntervalSinceNow: -60 * 60 * 24 * 3)
let threeDayBeforeNowDate = nowDate.addingTimeInterval(-60 * 60 * 24 * 3)

let diff_1 = threeDayBeforeNowDate_t1.timeIntervalSince(nowDate) - threeDayBeforeNowDate.timeIntervalSince(nowDate) // about 0.009357
let diff_2 = threeDayBeforeNowDate_t2.timeIntervalSince(nowDate) - threeDayBeforeNowDate.timeIntervalSince(nowDate) // about 0.010063
let diff_3 = threeDayBeforeNowDate_t2.timeIntervalSince(nowDate) - threeDayBeforeNowDate_t1.timeIntervalSince(nowDate) // about 0.000416

let calendar = Calendar.current
calendar.dateComponents(Set([Calendar.Component.day]), from: threeDayBeforeNowDate, to: oneDayAfterNowDate) // result = "day: 4 isLeapMonth: false"
calendar.dateComponents(Set([Calendar.Component.day]), from: threeDayBeforeNowDate_t1, to: oneDayAfterNowDate) // day: 4 isLeapMonth: false
calendar.dateComponents(Set([Calendar.Component.day]), from: threeDayBeforeNowDate_t2, to: oneDayAfterNowDate) // day: 3 isLeapMonth: false 

我不明白,为什么我得到如此不同的结果,而日期(threeDayBeforeNow ...)相差不到一秒。

2 个答案:

答案 0 :(得分:1)

问题是在创建nowDate和您使用Date(timeIntervalSinceNow:)初始化程序的其他变量之间需要一段时间。

Date()Date(timeIntervalSinceNow:)都使用系统时间来获取执行到达特定变量时的当前时间。无论多小,在不同的系统时间调用之间总会有一些小的延迟,因此即使你在两个连续的代码行中使用Date创建了两个Date()个对象,它们也不代表完全相同的时间点。

在Playground中运行,以下代码显示了这种行为:

let now1 = Date()
let now2 = Date()
now1.timeIntervalSince(now2) //-0.0002049803733825684

如果您想要一致的Date个对象,请创建一个单独的变量,在其中存储创建日期,使用Date(),就像nowDate那样,然后使用使用Date创建其他nowDate.addingTimeInterval()个对象的相同变量,就像您目前为threeDayBeforeNowDate所做的那样。

答案 1 :(得分:1)

作为Dávid already explained,问题在于各种日期 在不同的时间点计算,因此差异不是 恰好4天。特别是,之间的区别 threeDayBeforeNowDate_t2oneDayAfterNowDate 4天,这就是为什么差异的.day分量为3

这是一个演示问题的简化示例(在Playground中):

let nowDate = Date()
let date1 = Date(timeIntervalSinceNow: -60 * 60 * 24 * 4)
let date2 = nowDate.addingTimeInterval(-60 * 60 * 24 * 4)

let calendar = Calendar.current
calendar.dateComponents([.day, .hour, .minute, .second, .nanosecond], from: date1, to: nowDate)
// day: 3 hour: 23 minute: 59 second: 59 nanosecond: 994143066 isLeapMonth: false

calendar.dateComponents([.day, .hour, .minute, .second, .nanosecond], from: date2, to: nowDate)
// day: 4 hour: 0 minute: 0 second: 0 nanosecond: 0 isLeapMonth: false

date2nowDate恰好相差4天,但date1nowDate 差异很小小于 4天(假设没有 在这个时间段内的夏令时过渡。)