Moment.js UTC日期字符串显示正确但isBefore比较结果异常
问题根源
你得到的比较结果是正确的,出现认知偏差的核心原因是两个Moment实例的时区模式不统一,你被日志打印的带时区偏移的时间字符串误导了:
moment.utc()生成的是UTC模式实例,打印出的2022-07-13T13:47:39Z就是对应的UTC绝对时间- 直接调用
moment(时间戳)生成的是本地时区模式实例,你日志里的2022-07-13T14:45:00+04:00是东四区的本地时间,换算成UTC时间需要减去4小时,实际对应的UTC时间是2022-07-13T10:45:00Z,比currentDate的13:47:39Z早了3个多小时,所以isBefore返回false完全符合逻辑。
你现在用的替换Z字符的写法属于非标准hack,会引入额外的时间解析误差,不推荐使用。
标准处理方案
Moment原生提供了统一时区处理的API,不需要自行hack字符串,只要保证参与比较的两个实例处于同一个时区模式即可,常用两种方案:
方案1:统一用UTC模式解析所有时间
所有时间都用moment.utc()方法解析,从根源上统一时区模式:
const clientTimestamp = 1657709100000 const currentDate = moment.utc() // 时间戳同样使用utc模式解析 const clientDate = moment.utc(clientTimestamp) console.log('currentDate', currentDate) // 2022-07-13T13:47:39Z console.log('clientDate', clientDate) // 2022-07-13T10:45:00Z console.log(currentDate.isBefore(clientDate)) // 返回false,符合实际时间先后
方案2:直接比较原始时间戳
Unix毫秒时间戳是无时区概念的绝对时间值,不管Moment实例用什么时区模式,调用valueOf()就能拿到原始的毫秒时间戳,直接比较数值不会有任何偏差:
const clientTimestamp = 1657709100000 const currentDate = moment.utc() const clientDate = moment(clientTimestamp) // 直接比较原始毫秒时间戳 console.log(currentDate.valueOf() < clientDate.valueOf())
提示:只要传入Moment的时间戳数值正确,任何时区模式下调用
valueOf()取到的原始时间都不会变,所有时间比较异常本质都是时区模式不统一,导致打印出的本地时间字符串和UTC时间混淆,误判了时间先后。
内容的提问来源于stack exchange,提问作者lutaev
相关产品推荐
相关产品推荐

