You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

JavaScript中setHours函数为何会修改日期?附实际场景代码

为什么调用setHours会修改日期?

首先得明确一个核心点:JavaScript的Date对象同时关联着UTC时间和本地时区时间,而setDatesetHours这类方法都是基于本地时区来操作的。你遇到的问题,本质是时区偏移导致的UTC日期变化,或是操作时不小心跨了日期边界。

具体原因拆解

我们结合你给出的时间戳1578558324000一步步分析:

  1. 这个时间戳对应的UTC时间2020-01-09T05:05:24.000Z,如果你的本地时区是东八区(比如中国),那么本地时间就是2020-01-09 13:05:24
  2. const nextDay = new Date(day):这一步确实创建了一个新的Date实例,和day的UTC时间完全一致。
  3. nextDay.setDate(nextDay.getDate() + 1)getDate()获取的是本地时区的日期(这里是9),加1后设置为10,所以nextDay的本地时间变成2020-01-10 13:05:24,对应的UTC时间是2020-01-10T05:05:24.000Z
  4. nextDay.setHours(0,0,0,0):这个方法会把本地时区的时间强制设为00:00:00,所以nextDay的本地时间变成2020-01-10 00:00:00,但对应的UTC时间却变成了2020-01-09T16:00:00.000Z

这时候如果你的控制台默认显示UTC时间(或者你关注的是UTC日期),就会看到日期从10号变回9号,看起来像是setHours修改了日期,但实际上本地日期并没有改变——只是UTC日期因为时区偏移发生了变化。

另外还有一种少见的情况:如果你的时区涉及夏令时切换,在切换当天操作时,setDatesetHours可能因为小时数的增减(比如夏令时开始当天少1小时,结束当天多1小时),导致日期意外调整。

正确实现“加1天并设置为00:00:00”的方法

如果你想要的是本地时区的次日00:00:00,可以调整操作顺序,先设置时间再加日期,这样更稳妥:

const day = new Date(1578558324000)
const nextDay = new Date(day)
// 先把时间设为本地00:00:00
nextDay.setHours(0, 0, 0, 0)
// 再加1天
nextDay.setDate(nextDay.getDate() + 1)
console.log(day)
console.log(nextDay)

如果你想要的是UTC时区的次日00:00:00,应该使用UTC专属方法,彻底避免时区干扰:

const day = new Date(1578558324000)
const nextDay = new Date(day)
// 基于UTC操作:先设为UTC 00:00:00,再加1天
nextDay.setUTCHours(0, 0, 0, 0)
nextDay.setUTCDate(nextDay.getUTCDate() + 1)
console.log(day)
console.log(nextDay)

总结

  • setHours本身不会主动修改本地日期,但如果设置的时间在时区转换后跨越了UTC日期边界,会导致UTC日期变化,给人一种“日期被修改”的错觉。
  • 操作日期时,一定要明确是基于本地时区还是UTC时区,选择对应的方法(带UTC前缀的方法是基于UTC操作的)。

内容的提问来源于stack exchange,提问作者Mahmudul Hasan

火山引擎 最新活动