CareKit数据同步Firebase后日期为浮点数,是否损坏?转换失败如何解决?
结论
你的CareKit数据没有损坏,Firebase中存储的浮点型日期是Apple平台的标准时间存储格式,本身不存在异常。
原因说明
Apple体系下的Date类型底层基于 CFAbsoluteTime 标准,时间计算基准为2001-01-01 00:00:00 UTC,和通用Unix时间戳的1970年基准相差978307200秒。你之前用BigQuery转换失败,就是因为直接按1970年基准的Unix时间戳处理导致的。
比如你示例中的updatedDate值646268927.410913,加上基准差978307200后得到的1624576127.410913,就是标准Unix时间戳,对应时间就是你日志里输出的2021-08-15 23:28:52 UTC。
解决方案
方案1:修正BigQuery转换语句
直接在原有转换逻辑中加上2001和1970的基准差值即可,需要保留毫秒精度可以用以下语句:
SELECT FORMAT_TIMESTAMP( "%Y-%m-%d %H:%M:%E3S", TIMESTAMP_MICROS(CAST((updatedDate + 978307200) * 1000000 AS INT64)), "Asia/Tokyo" ) as formatted_date FROM `你的表名`
如果不需要毫秒精度,简化为:
SELECT FORMAT_TIMESTAMP( "%Y-%m-%d %H:%M:%S", TIMESTAMP_SECONDS(CAST(updatedDate + 978307200 AS INT64)), "Asia/Tokyo" ) as formatted_date FROM `你的表名`
方案2:上传Firebase时统一时间格式(可选)
如果希望后续处理更方便,可以在编码上传阶段就把时间转为通用格式,不会影响CareKit的正常解析:
在你putRevisionInFirestore方法的JSONEncoder()初始化后,添加日期编码策略配置即可:
let encoder = JSONEncoder() // 选择任意一种即可,解码时对应配置相同策略 encoder.dateEncodingStrategy = .secondsSince1970 // 1970基准Unix时间戳 // encoder.dateEncodingStrategy = .iso8601 // 可读性更高的ISO标准字符串 let data = try encoder.encode(deviceRevision)
解码时也要给JSONDecoder配置相同的日期解码策略:
let decoder = JSONDecoder() decoder.dateDecodingStrategy = .secondsSince1970 // 和编码策略对应 // decoder.dateDecodingStrategy = .iso8601 let revisions = try decoder.decode([OCKRevisionRecord].self, from: jsonData)
内容的提问来源于stack exchange,提问作者user2677680
相关产品推荐
相关产品推荐

