如何避免toISOString()转换时改变日期?保持原年月日不变
解决Date转ISO字符串时日期偏移的问题
这个问题我之前也碰到过!核心原因是toISOString()方法会强制转换为UTC时间,而你用new Date('4/7/2018')创建的日期是基于你的本地时区的「4月7日00:00:00」。如果你的本地时区比UTC晚(比如UTC-4、UTC-5这类美洲时区),那本地的4月7日零点对应到UTC就是4月6日的下午/晚上,所以输出的ISO字符串日期就变成6号了。
下面给你几种靠谱的解决方法,保证能得到和原年月日一致的ISO格式字符串:
方法1:手动构造ISO格式字符串
直接提取日期的本地年、月、日等信息,手动拼接成符合ISO标准的字符串,完全避开UTC转换的问题:
const date = new Date('4/7/2018'); const year = date.getFullYear(); // 月份是0开始的,所以要+1,并且补两位 const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); const hours = String(date.getHours()).padStart(2, '0'); const minutes = String(date.getMinutes()).padStart(2, '0'); const seconds = String(date.getSeconds()).padStart(2, '0'); const ms = String(date.getMilliseconds()).padStart(3, '0'); // 拼接成ISO格式,最后加Z表示UTC规范 const isoString = `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${ms}Z`; console.log(isoString); // 输出 "2018-04-07T00:00:00.000Z"(如果本地时间是零点的话)
方法2:将本地时间同步到UTC时间
通过setUTCHours()把本地时间的时分秒毫秒设置到UTC时区上,这样toISOString()就会输出和本地年月日一致的结果:
const date = new Date('4/7/2018'); // 把本地的时分秒毫秒赋值给UTC的时分秒毫秒 date.setUTCHours( date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds() ); const isoString = date.toISOString(); console.log(isoString); // 输出 "2018-04-07Txx:xx:xx.xxxZ",xx是你本地的时分秒
方法3:使用现代浏览器支持的国际化API
如果你不需要严格的带Z的UTC格式,只是要ISO样式的字符串,也可以用Intl.DateTimeFormat来格式化:
const date = new Date('4/7/2018'); const isoString = new Intl.DateTimeFormat('en-CA', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', fractionalSecondDigits: 3, timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone // 使用本地时区 }).format(date).replace(', ', 'T') + 'Z'; console.log(isoString); // 输出符合要求的ISO格式字符串
注意:fractionalSecondDigits是ES2021新增的属性,旧浏览器可能不支持,如果不需要毫秒可以直接去掉这个配置项。
内容的提问来源于stack exchange,提问作者Hommer Smith
相关产品推荐
相关产品推荐

