如何正确计算Timestamp与DateTime的分钟/天级时间差
正确计算Firebase Timestamp与DateTime时间差的方法
异常原因
两个时间值直接计算出现错误差值、异常负值的核心原因是时区不统一:
DateTime.now()生成的对象默认使用本地时区,isUtc属性为false- Firebase
Timestamp调用toDate()返回的是UTC时区的DateTime对象,isUtc属性为true
跨时区的两个DateTime对象直接调用difference()时,会把时区偏移量算入差值,哪怕两个时间的实际间隔只有几毫秒,最终结果也会带上几小时的固定时区误差,出现不符合预期的数值。
正确实现方案
两种方案都可以准确计算分钟、天维度的时间差,根据使用习惯选择即可:
方案1:统一时区后计算
把两个时间转换为同一时区后再调用差值方法,推荐统一转UTC,避免本地时区夏令时等特殊规则影响:
Timestamp myTimestamp = // 从Firebase字段获取的时间戳 DateTime myDateTime = DateTime.now(); // 将当前时间转为UTC,和Timestamp输出的UTC时间对齐 Duration timeDiff = myDateTime.toUtc().difference(myTimestamp.toDate()); // 也可以选择把Timestamp的时间转成本地时区对齐 // Duration timeDiff = myDateTime.difference(myTimestamp.toDate().toLocal()); // 输出分钟维度差值 int diffInMinutes = timeDiff.inMinutes; // 输出天维度差值 int diffInDays = timeDiff.inDays;
方案2:直接通过绝对毫秒数计算(最稳妥)
毫秒级时间戳是从1970-01-01 UTC零点开始计算的绝对偏移值,完全不受时区影响,不会出现时区带来的计算误差:
Timestamp myTimestamp = // 从Firebase字段获取的时间戳 DateTime myDateTime = DateTime.now(); // 直接用两个时间的毫秒偏移量计算差值 Duration timeDiff = Duration( milliseconds: myDateTime.millisecondsSinceEpoch - myTimestamp.millisecondsSinceEpoch ); // 输出分钟、天维度结果 int diffInMinutes = timeDiff.inMinutes; int diffInDays = timeDiff.inDays;
注意:
difference的计算逻辑是「调用方时间 - 传入参数时间」,如果计算结果为负,说明传入参数的时间晚于调用方的时间,根据业务需要核对两个时间的传入顺序即可。
内容的提问来源于stack exchange,提问作者Mohammed Hamdan
相关产品推荐
相关产品推荐

