日历:获取日期组件,奇怪的情况
Calendar: get date components, weird case
我想找出为什么这段代码运行起来如此奇怪。您可以在下面找到详细信息:
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...)相差不到一秒的情况下得到如此不同的结果。
问题是在创建 nowDate
和您使用 Date(timeIntervalSinceNow:)
初始化器的其他变量之间经过了一些时间。
Date()
和Date(timeIntervalSinceNow:)
都使用系统时间来获取执行到达特定变量时的当前时间。不管有多小,对系统时间的不同调用之间总会有一些小的延迟,因此即使您在连续两行代码中使用 Date()
创建两个 Date
对象,它们也不会代表完全相同的时间点。
运行 在 Playground 中,以下代码段显示了此行为:
let now1 = Date()
let now2 = Date()
now1.timeIntervalSince(now2) //-0.0002049803733825684
如果您想要一致的 Date
个对象,请创建一个变量,在其中存储创建日期,使用 Date()
就像您目前对 nowDate
所做的那样,然后使用相同的变量使用 nowDate.addingTimeInterval()
创建其他 Date
对象,就像您当前为 threeDayBeforeNowDate
.
所做的那样
如,问题是各种日期
是在不同的时间点计算的,因此差异不大
刚好4天。特别是,两者之间的区别
threeDayBeforeNowDate_t2
和 oneDayAfterNowDate
比 少
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
date2
和 nowDate
正好相差 4 天,但是 date1
和 nowDate
相差 小于 4 天(假设没有
此时间跨度内的夏令时转换)。
我想找出为什么这段代码运行起来如此奇怪。您可以在下面找到详细信息:
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...)相差不到一秒的情况下得到如此不同的结果。
问题是在创建 nowDate
和您使用 Date(timeIntervalSinceNow:)
初始化器的其他变量之间经过了一些时间。
Date()
和Date(timeIntervalSinceNow:)
都使用系统时间来获取执行到达特定变量时的当前时间。不管有多小,对系统时间的不同调用之间总会有一些小的延迟,因此即使您在连续两行代码中使用 Date()
创建两个 Date
对象,它们也不会代表完全相同的时间点。
运行 在 Playground 中,以下代码段显示了此行为:
let now1 = Date()
let now2 = Date()
now1.timeIntervalSince(now2) //-0.0002049803733825684
如果您想要一致的 Date
个对象,请创建一个变量,在其中存储创建日期,使用 Date()
就像您目前对 nowDate
所做的那样,然后使用相同的变量使用 nowDate.addingTimeInterval()
创建其他 Date
对象,就像您当前为 threeDayBeforeNowDate
.
如threeDayBeforeNowDate_t2
和 oneDayAfterNowDate
比 少
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
date2
和 nowDate
正好相差 4 天,但是 date1
和 nowDate
相差 小于 4 天(假设没有
此时间跨度内的夏令时转换)。