JavaScript中new Date()指定日期字符串在不同时区返回不同日期的问题
为什么
new Date('2020-08-28')在不同时区返回不同日期?怎么忽略时区影响? 这是JavaScript日期处理里一个非常典型的「标准规定」坑,我来给你掰明白:
问题原因
当你传入'YYYY-MM-DD'这种ISO 8601格式的日期字符串时,ECMAScript标准明确要求:JavaScript引擎会把这个字符串解析为UTC时间的午夜(00:00:00),然后再转换为当前设备的本地时区时间显示。
对应你的例子:
- 印度时区(IST)比UTC快5小时30分钟:UTC的2020-08-28 00:00:00加上5:30,就是本地时间的2020-08-28 05:30:00,所以日志显示当天日期。
- 美国中部时区(CST)比UTC慢5小时:UTC的2020-08-28 00:00:00减去5小时,就是本地时间的2020-08-27 19:00:00,所以日志显示前一天的日期。
这完全是标准规定的行为,不是代码写错了哦。
解决方法:忽略时区影响的两种常见场景
场景1:想创建本地时区的当天0点(不管设备时区,都指向本地日期的午夜)
不要用ISO格式的字符串,直接用Date构造函数的年、月、日参数(注意月份是0-based,即1月对应0,8月对应7):
// 创建本地时区的2020年8月28日00:00:00 const localDate = new Date(2020, 7, 28); console.log(localDate); // IST时区显示:Fri Aug 28 2020 00:00:00 GMT+0530 // CST时区显示:Fri Aug 28 2020 00:00:00 GMT-0500
场景2:想创建UTC时区的当天0点,且操作日期时不受本地时区干扰
用Date.UTC()方法生成UTC时间戳,再传给Date构造函数。如果要获取日期的年、月、日,记得用UTC对应的方法(比如getUTCFullYear()而不是getFullYear()):
// 创建UTC时间的2020年8月28日00:00:00 const utcDate = new Date(Date.UTC(2020, 7, 28)); console.log(utcDate); // IST时区显示:Fri Aug 28 2020 05:30:00 GMT+0530 // CST时区显示:Thu Aug 27 2020 19:00:00 GMT-0500 // 但获取UTC日期部分时,结果一致: console.log(utcDate.getUTCFullYear()); // 2020 console.log(utcDate.getUTCMonth() + 1); // 8 console.log(utcDate.getUTCDate()); // 28
另外补充个小技巧:如果一定要用字符串格式,也可以改成非ISO的分隔符(比如'2020/08/28'),大部分浏览器会把这种格式解析为本地时区的午夜,但这种行为没有标准强制保证,所以还是推荐用构造函数参数的方式更可靠。
内容的提问来源于stack exchange,提问作者vishal kokate




