以纳秒为单位的快速日期差异不起作用

Posted

技术标签:

【中文标题】以纳秒为单位的快速日期差异不起作用【英文标题】:Swift date difference in nanoseconds is not working 【发布时间】:2021-07-24 20:34:54 【问题描述】:

我正在实现一个计时器,该计时器需要计算用户处于非活动状态的毫秒数并计算差异并恢复计时器。由于 dateComponents 中没有毫秒选项,因此我使用了纳秒,但是,当我尝试计算两个日期之间的纳秒间隔时,每次都会得到相同的结果(当前日期正在改变,应该得到不同的结果),如果我改变纳秒到秒,它的工作原理。我执行了两次进行实验。

let d1 = Date()
let df = DateFormatter()
df.dateFormat = "y-MM-dd H:m:ss.SSSS"
let d2 = df.date(from: "2021-05-03 9:30:00.1234")!

print(df.string(from: d1)) 
print(df.string(from: d2)) 
print(Calendar.current.dateComponents([.second], from: d1, to: d2).second!) 
// result1: "85573"
// result2: "85067"

当我使用纳秒时

let d1 = Date()
let df = DateFormatter()
df.dateFormat = "y-MM-dd H:m:ss.SSSS"
let d2 = df.date(from: "2021-05-03 9:30:00.1234")!

print(df.string(from: d1))
print(df.string(from: d2))
print(Calendar.current.dateComponents([.nanosecond], from: d1, to: d2).nanosecond!)
// result1: "2147483647"
// result2: "2147483647"

【问题讨论】:

【参考方案1】:

虽然我找不到它的记录:似乎所有日期组件的可能值都限制为带符号的 32 位整数,超出该范围的值被截断为 Int32.max = 2147483647 Int32.min = -2147483648:

let d1 = Date()
let d2 = d1.addingTimeInterval(2)
print(Calendar.current.dateComponents([.nanosecond], from: d1, to: d2).nanosecond!)
// 2000000000
let d3 = d1.addingTimeInterval(3)
print(Calendar.current.dateComponents([.nanosecond], from: d1, to: d3).nanosecond!)
// 2147483647
let d4 = d1.addingTimeInterval(-3)
print(Calendar.current.dateComponents([.nanosecond], from: d1, to: d4).nanosecond!)
// -2147483648

如果您同时请求秒和纳秒,则纳秒组件仅包含小数秒,这会使您的代码再次产生正确的结果:

print(Calendar.current.dateComponents([.second, .nanosecond], from: d1, to: d2))
// Example output:
// second: 111403 nanosecond: 464950927 isLeapMonth: false

如果你只需要以毫秒为单位的两个时间点之间的差异,那么

let elapsed = Int(d2.timeIntervalSince(d1) * 1000)

是一个更简单的选择。

【讨论】:

【参考方案2】:

不需要所有的日期组件。只需在每个日期上使用timeIntervalSinceReferenceDate 从另一个日期中减去一个日期。或者:

https://developer.apple.com/documentation/foundation/date/3329238-distance

结果以秒为单位,精确到毫秒,因此乘以 1000 即可。

【讨论】:

只是提到distance(to:)timeIntervalSince(_:)没有区别:github.com/apple/swift-corelibs-foundation/blob/main/Sources/…。 – 出于某种原因,Date 定义了 StrideStrideable 协议所需的所有方法,但不符合该协议。 @MartinR 在大街上的一句话是他们对 Stridable 的尝试感到抱歉,distance 可能会被撤回。我对推荐它有点紧张。

以上是关于以纳秒为单位的快速日期差异不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Html 表格以 px 为单位指定列宽不起作用

Angularjs日期过滤器将时间毫秒转换为UTC不起作用

日期部分标题不起作用

jQuery DatePicker:当日期字段为 12-31-9999 时,currentDate 不起作用

生成 forIndexName 的 Liquibase 差异在 h2 上不起作用

使用单位矩阵的坐标不起作用[重复]