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

问题描述

我正在实现一个计时器,它需要计算用户处于非活动状态的毫秒数并计算差异并恢复计时器。由于 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],to: d2).nanosecond!)
// result1: "2147483647"
// result2: "2147483647"

解决方法

虽然我找不到它的文档:似乎所有日期组件的可能值仅限于有符号 32 位整数的值,并且该范围之外的值被截断为 Int32.max = 2147483647 或 {{1 }}:

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],to: d3).nanosecond!)
// 2147483647
let d4 = d1.addingTimeInterval(-3)
print(Calendar.current.dateComponents([.nanosecond],to: d4).nanosecond!)
// -2147483648

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

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

是一个更简单的选择。

,

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

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

结果以秒为单位,精确到毫秒,所以乘以 1000 就完成了。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...