关于JavaScript getTime()方法返回结果不符合预期的技术咨询
让我来帮你理清这个困惑——核心问题其实出在你对两个Date构造调用所代表的时刻理解上,咱们一步步拆解:
先明确两个Date构造的本质区别
new Date(Date.UTC(2021,8,1)):
这里Date.UTC(2021,8,1)直接生成了UTC时区2021年9月1日00:00:00对应的时间戳,再传给Date构造函数,所以这个Date对象指向的就是UTC标准下的这个时刻。它的getTime()返回的就是从1970-01-01 UTC到这个时刻的毫秒数:1630454400000。new Date(2021,8,1):
这个构造的参数是按本地时区解析的年、月、日(注意JS里月份是0索引,8对应9月),所以它指向的是你本地时区(UTC+1)的2021年9月1日00:00:00。而这个时刻对应的UTC时间其实是2021年8月31日23:00:00,所以它的getTime()返回的是到这个UTC时刻的毫秒数:1630447200000。
问题A解答:为什么预期一致但结果不同?
你误解了文档描述的场景——文档说getTime()始终采用UTC表示时间,意思是同一个物理时刻,不管在哪个时区调用getTime()结果都一致。但你例子里的两个Date对象,指向的是完全不同的物理时刻:一个是UTC的9月1日零点,另一个是UTC+1的9月1日零点(对应UTC的8月31日23点)。这两个时刻之间差了1小时,所以从1970年到它们的时间流逝长度自然不同,getTime()结果不一致是完全正常的。
举个直观的例子:如果UTC时区的用户在8月31日23点调用new Date().getTime(),和UTC+1时区的用户在9月1日零点调用同一个方法,得到的结果会完全相同——因为他们记录的是同一个物理时刻。
问题B解答:为什么结果少1小时?
你逻辑里搞反了时区的对应关系:UTC+1时区比UTC快1小时,意味着当UTC+1时区已经到9月1日零点时,UTC时区还停留在8月31日23点。而getTime()的本质是返回对应UTC时刻到1970年的毫秒数,所以UTC+1的9月1日零点,对应的UTC时刻更早,自然时间戳更小,比UTC的9月1日零点少了1小时的毫秒数(3600000)。
你可以通过打印UTC字符串验证这一点:
console.log(new Date(Date.UTC(2021,8,1)).toUTCString()); // 输出: Wed, 01 Sep 2021 00:00:00 GMT console.log(new Date(2021,8,1).toUTCString()); // 输出: Tue, 31 Aug 2021 23:00:00 GMT
很明显,两个Date对象对应的UTC时刻差了1小时,所以getTime()结果的差异也就顺理成章了。
内容的提问来源于stack exchange,提问作者Bernd

