【问题标题】: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"

【问题讨论】:

    标签: ios swift date nsdateformatter nsdatecomponents


    【解决方案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 可能会被撤回。我对推荐它有点紧张。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-27
      • 1970-01-01
      • 2015-10-09
      • 2020-09-29
      • 1970-01-01
      • 2011-08-24
      相关资源
      最近更新 更多