Swift timeIntervalSince1970转换为Firebase Cloud Tasks所需Epoch秒数方案咨询
问题描述
我参考了两处技术社区回答的内容。
我刚从一篇技术博客开始学习Cloud Tasks,博文中Doug提到:我需要将expirationAtSeconds设置为以epoch seconds表示的过期时间。
我的需求是让Cloud Task在指定时间自动删除帖子,我在iOS应用中创建带过期时间的帖子,代码如下:
let timeStamp = Date().timeIntervalSince1970 let postDate: Date = Date(timeIntervalSince1970: timeStamp) var expirationDate: Date? = Calendar.current.date(byAdding: .hour, value: +24, to: postDate) guard let exp = expirationDate else { return } let expiresAt = exp.timeIntervalSince1970 dict.updateValue(expiresAt, forKey: "expiresAt") dict.updateValue(timeStamp, forKey: "postDate") // 其他值 ... ref.updateChildValues(dict)
最终数据库中的存储值示例如下:
posts some_post_Id -"expiresAt": 1632627680.340107 // 其他值 ...
我在云函数中需要将Double类型的expiresAt转换为Epoch秒格式,不确定应该使用expDate1、expDate2、expDate3还是expDate4,云函数代码如下:
exports.onCreatePost = functions.database.ref('/posts/{postId}').onCreate((snapshot, context) => { const post = snapshot.data(); const expiresAt = snapshot.child("expiresAt").val(); const expirationDate = expiresAt.valueOf(); // 1632627680.340107 var expDate1 = DateTime.fromMillisecondsSinceEpoch(expirationDate * 1000) var expDate2 = DateTime.fromMicrosecondsSinceEpoch(expirationDate * 1000000) var expDate3 = DateTime.fromMicrosecondsSinceEpoch(expirationDate.microsecondsSinceEpoch) var expDate4 = expirationDate.toDate() const expirationAtSeconds = either expDate1, expDate2, expDate3, or expDate4 // 剩余代码继续... });
请问我应该选择哪种转换方式,才能得到Cloud Tasks要求的epoch seconds格式?
解答
首先明确两个基础前提:
- 你在iOS端通过
timeIntervalSince1970生成的expiresAt本身就是以秒为单位的epoch时间,小数点后是亚秒级的精度部分。 - Cloud Tasks要求的
expirationAtSeconds为整数形式的epoch秒数,对亚秒精度没有要求。
四个可选转换方式的正误分析如下:
expDate1:正确。你的expirationDate是秒级单位,乘以1000后正好转换为毫秒级的epoch时间戳,传入fromMillisecondsSinceEpoch方法可以得到完全准确的DateTime对象,后续调用.toSeconds()取整即可得到符合要求的expirationAtSeconds。expDate2:可用但冗余。乘以1000000转成微秒级时间戳构造DateTime对象没有问题,但是Cloud Tasks调度精度到秒即可,不需要到微秒级,属于不必要的操作。expDate3:错误。你从数据库中读取到的expirationDate是纯Double类型数值,没有microsecondsSinceEpoch属性,运行时会直接报错。expDate4:错误。toDate()是Firestore Timestamp类型的专属方法,你存储的是普通Double数值不是Timestamp对象,调用会直接报错。
如果你的目标只是拿到符合要求的expirationAtSeconds,甚至不需要转换成DateTime对象,直接对读取到的expiresAt取整即可:
const expirationAtSeconds = Math.round(expiresAt)
该写法更简洁高效,完全满足Cloud Tasks的格式要求。
内容的提问来源于stack exchange,提问作者Lance Samaria
相关产品推荐
相关产品推荐

