JavaScript Date时间戳处理函数在浏览器和Jest环境运行结果不一致问题
问题核心原因
- 你调用
new Date(year, month, day, ...)传入日期分量时,JS默认会按照运行环境的本地时区解析这些分量,而非UTC时区,这是所有问题的根源。 - 你传入的入参
new Date(2021, 4, 16)同样是按照本地时区构造的,你的当前时区为GMT+2,这个日期对应的UTC时间实际是2021-05-15T22:00:00.000Z,调用getUTCDate()拿到的日期是15而非你预期的16。
现象解释
两个环境的输出本质是同一个时间,只是默认展示格式不同:
- 浏览器默认调用
Date.toString()输出本地时区时间:你构造出的是GMT+2时区的2021-05-15 00:00:00,对应输出就是你看到的Sat May 15 2021 00:00:00 GMT+0200。 - Jest环境默认将时区设为UTC,直接输出时间的UTC表示:上述GMT+2的零点对应UTC时间就是前一天的22点,即
2021-05-14T22:00:00.000Z,和浏览器结果完全一致,不存在冲突。
修复方案
如果你的需求是将输入日期对应的UTC日期的时间清零到UTC 0点,需要使用Date.UTC()方法将分量解析为UTC时间再传入Date构造函数:
const removeDateTimestamp = (date) => { return new Date(Date.UTC( date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 0, 0, 0, 0 )); };
同时单元测试需要做两处调整:
- 入参如果要指定UTC的2021年5月16日,需要用
Date.UTC构造,避免本地时区影响 - 匹配前先调用
toISOString()将Date对象转为UTC格式字符串,不要直接匹配Date对象
it("removeDateTimestamp", () => { const input = new Date(Date.UTC(2021, 4, 16)); expect(removeDateTimestamp(input).toISOString()).toMatch( /2021-05-16T00:00:00.000Z/i ); });
内容的提问来源于stack exchange,提问作者user7494479
相关产品推荐
相关产品推荐

