为了账号安全,请及时绑定邮箱和手机立即绑定

如何处理 Garmin 设备中的 timestamp_16?

如何处理 Garmin 设备中的 timestamp_16?

凤凰求蛊 2022-05-19 15:38:46
我拥有一个 Garmin Vivosport,我用它来跟踪我的活动和睡眠,我想对我自己的心率数据进行一些分析,这些数据来自我通过 Garmin Connect 下载的 FIT 文件。问题是我无法正确对齐时间戳。此处提出了类似的问题,但我没有找到答案,也无法发表评论以添加我的问题。正如这里所解释的,在 FIT 文件中,时间戳信息被分成两个不同的变量:一个timestamp不时出现的变量,以及一个timestamp_16附加到每个单独测量的变量。根据他们的说法,timestamp_16包含实际时间戳的低 16 位,因此它应该与前一个的高 16 位组合timestamp。我使用的是 2019 年 5 月 1 日记录的数据。文件涵盖一天中的 24 小时,因此第一个数据点是 00:00(我在 Garmin Connect 的图形界面中检查了这一点,并且事情匹配)。在这个文件中,我发现这是第一个感兴趣的数据条目:monitoring * activity_type: sedentary * current_activity_type_intensity: (8,) * intensity: 0 * timestamp: 2019-04-30 22:00:00[some other lines in between]monitoring * heart_rate: 72 * timestamp_16: 31132上面的第一个对象在包含心率的对象之前monitoring剪断了最后一个包含 a 的对象,因此它与链接说明中所写的内容相匹配。timestamp有了这些信息,我尝试了一些解决方案,但没有一个解决方案我设法将文件中第一个数据点的实际时间戳设为 2019 年 5 月 1 日 00:00(也不是在几分钟内)。如果我按照上面链接中给出的说明进行操作,我会得到:mesgTimestamp = timestampmesgTimestamp += ( timestamp_16 - ( mesgTimestamp & 0xFFFF ) ) & 0xFFFF但结果是:2019-05-01 12:49:00我还尝试手动替换 with 的低 16 位timestamp,timestamp_16但同样没有成功:timestamp    :   0b1011100110010001011111001011000timestamp_16 :                   0b111100110011100result       :   0b1011100110010000111100110011100datetime以上对应的result值为datetime.datetime(2019, 4, 30, 18, 36, 44)。这是我所有尝试的代码。 这是一个正在讨论的github问题。正如您在上面看到的,我无法得到正确的结果,即 2019 年 5 月 1 日 00:00。除此之外,如果我在位级别上手动应用 Garmin 的配方,与应用他们给出的公式相比,我会得到不同的结果。此外,我得到的结果在非零分钟和秒的时间内被关闭,这让我相信这不是时区问题(我也尝试使用它但没有成功)。有没有人找到一个稳定的解决方案?如果你有的话,你能分享一下吗(还有其他语言,我对这里的逻辑感兴趣)?几个月以来我一直在努力解决这个问题(在我的业余时间做这件事),但这种缺乏结果真的令人沮丧:\
查看完整描述

1 回答

?
倚天杖

TA贡献1828条经验 获得超3个赞

考虑到特殊的 Garmin 纪元,它比 Unix 时间戳纪元晚了 631065600 秒,计算需要在那个特殊的时间发生(如果它只是一个正常的偏移量就不会出现这种情况,但这些偏移量并不是严格相加的所以时间的“绝对价值”很重要)。只需减去 631065600:


dt_offset = datetime.datetime(2019,4,30,22,0,0,0)

timestamp = int(datetime.datetime.timestamp(dt_offset)) - 631065600

timestamp_16 = 31132

以任何合理的方式应用时间增量,例如:


mesgTimestamp = timestamp

mesgTimestamp += ( timestamp_16 - ( mesgTimestamp & 0xFFFF ) ) & 0xFFFF

或者:


mesgTimestamp = timestamp + ((timestamp_16 - timestamp) & 0xffff)

或者:


mesgTimestamp = (timestamp & 0xffff0000) | timestamp_16

if mesgTimestamp < timestamp:

  mesgTimestamp += 0x10000

使用生成的时间戳时再次应用 Garmin 纪元偏移:


print('New:', datetime.datetime.fromtimestamp(mesgTimestamp + 631065600, pytz.timezone('Europe/Zurich')))

结果:New: 2019-05-01 00:01:00+02:00足够接近?


查看完整回答
反对 回复 2022-05-19
  • 1 回答
  • 0 关注
  • 164 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信