JavaScript中setHours函数为何会修改日期?附实际场景代码
为什么调用
setHours会修改日期? 首先得明确一个核心点:JavaScript的Date对象同时关联着UTC时间和本地时区时间,而setDate、setHours这类方法都是基于本地时区来操作的。你遇到的问题,本质是时区偏移导致的UTC日期变化,或是操作时不小心跨了日期边界。
具体原因拆解
我们结合你给出的时间戳1578558324000一步步分析:
- 这个时间戳对应的UTC时间是
2020-01-09T05:05:24.000Z,如果你的本地时区是东八区(比如中国),那么本地时间就是2020-01-09 13:05:24。 const nextDay = new Date(day):这一步确实创建了一个新的Date实例,和day的UTC时间完全一致。nextDay.setDate(nextDay.getDate() + 1):getDate()获取的是本地时区的日期(这里是9),加1后设置为10,所以nextDay的本地时间变成2020-01-10 13:05:24,对应的UTC时间是2020-01-10T05:05:24.000Z。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日期因为时区偏移发生了变化。
另外还有一种少见的情况:如果你的时区涉及夏令时切换,在切换当天操作时,setDate或setHours可能因为小时数的增减(比如夏令时开始当天少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




