时间戳CMLogItem:为什么这么复杂?

11
我从Swift的CoreMotion查询中接收到一个CMLogItem(可以是加速度计,陀螺仪)。现在,我想获取该样本的时间戳,最好是作为一个Date()对象。 CMLogItem具有.timestamp属性,其类型为TimeInterval
文档告诉我以下内容: “CMLogItem类定义了只读的时间戳属性,记录了测量运动事件时的时间。”
然而,我不确定如何将此时间戳转换为Date()对象,因为我不知道时间戳是指什么。
另一份文档说: “时间戳是自设备启动以来经过的秒数。”
但这似乎非常奇怪,我不理解为什么苹果会创建如此不一致和复杂的API。
2个回答

7

正确的答案是:

extension CMLogItem {
    static let bootTime = Date(timeIntervalSinceNow: -ProcessInfo.processInfo.systemUptime)

    func startTime() -> Date {
        return CMLogItem.bootTime.addingTimeInterval(self.timestamp)
    }
}

这使我们得到了稳定、单调的结果,而当每次调用startTime时都计算bootTime时,则不是这种情况。


是的,这是个好主意!只是提醒一下,在watchOS上,时间戳的计算方式不同: return Date(timeIntervalSinceReferenceDate: self.timestamp) - DeveloBär
@DeveloBär,你关于watchOS的说法是错误的,它不是那样工作的。我实施了你的方法,并发现当前iPhone时间戳和当前watchOS时间戳之间的差异约为900,000,000秒。 - omikron
我认为这不正确。第一次使用时可以正常工作,但在生产过程中,当应用程序运行一段时间后,设备休眠一段时间后,下一次的时间戳会出错... 我非常确定 bootTime 必须在每次应用程序被唤醒时刷新... 不仅仅是第一次。 - Herbert Poul

-1

我想我弄清楚了。

这里的文档有误。

它不是“自设备启动以来的秒数” - 它确实是自他们的参考日期以来的时间。

修复:

extension CMLogItem {
    func startTime() -> Date {
        #if os(watchOS)
        return Date(timeIntervalSinceReferenceDate: self.timestamp)
        #else
        let systemRebootTime = Date(timeIntervalSinceNow: -ProcessInfo.processInfo.systemUptime)
        return systemRebootTime.addingTimeInterval(self.timestamp)
        #endif
    }
}

1
错误。Date(timeIntervalSinceReferenceDate: )创建一个日期值,该值相对于2001年1月1日的00:00:00 UTC初始化,并给定一定数量的秒数。 - Hogdotmac
请详细说明这个有什么问题?时间戳似乎是相对于2001年的参考日期?! - DeveloBär
1
这是错误的,因为CMLogItem上的timestamp不是相对于参考日期(即2001年1月1日)的时间,而是相对于设备启动的时间。 - Legoless
已编辑上面的代码。这仅适用于watchOS。在iOS上,它似乎使用自上次重启以来的时间。 - DeveloBär
2
这个不起作用,会导致时间差异很大。而且,在watchOS和iPhone之间的时间戳之间存在更加复杂的关系。似乎它考虑了设备处于睡眠状态的时间长度。 - omikron
好的,我的说法是watchOS和iOS时间戳之间的关系与设备处于睡眠状态的时间长短有关是不正确的。我遇到了其他问题,与处理队列混乱有关,并且处理程序被延迟了。 - omikron

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接