Date.toLocaleString转换UTC时间异常:小时未重置为00
Date.toLocaleString 转UTC时间时出现24:xx而非00:xx的问题
问题描述
我在把Date对象转为UTC时间时,用Date.toLocaleString遇到了异常:
执行这段代码:
new Date('Tue Aug 09 2022 18:43:00 GMT-0500 (Central Daylight Time)') .toLocaleString('en-US', { timeZone: "UTC", day: "2-digit", hour12: false, year: "numeric", month: "2-digit", hour: '2-digit', minute: '2-digit', second: '2-digit', })
输出是正常的:"08/09/2022, 23:43:00"
但运行下面这段代码时:
new Date('Tue Aug 09 2022 19:43:00 GMT-0500 (Central Daylight Time)') .toLocaleString('en-US', { timeZone: "UTC", day: "2-digit", hour12: false, year: "numeric", month: "2-digit", hour: '2-digit', minute: '2-digit', second: '2-digit', })
结果是"08/10/2022, 24:43:00",而我预期应该是"08/10/2022, 00:43:00",小时没正确重置成00。
我现在靠正则匹配加判断临时解决了,但不想额外处理,想知道问题原因和正确实现方式。
问题原因
这是Intl.DateTimeFormat的旧版本实现bug,在部分旧浏览器(比如老版Chrome)或Node.js环境里,当配置hour12: false+hour: '2-digit'时,跨天到次日0点的UTC时间会被错误格式化为24,而不是标准的00。
按照24小时制规范,00代表新一天的开始,24仅用来表示当天的结束时刻(和次日0点等价),但格式化输出应该统一用00表示次日起始的小时。
正确解决方法
方法1:用hourCycle: 'h23'替代hour12: false
把原配置里的hour12: false去掉,换成hourCycle: 'h23',明确指定使用00-23的24小时制格式,同时保留hour: '2-digit'保证两位数输出:
new Date('Tue Aug 09 2022 19:43:00 GMT-0500 (Central Daylight Time)') .toLocaleString('en-US', { timeZone: "UTC", day: "2-digit", year: "numeric", month: "2-digit", hour: '2-digit', minute: '2-digit', second: '2-digit', hourCycle: 'h23' // 核心修正配置 })
执行后会正确输出:"08/10/2022, 00:43:00"
方法2:升级运行环境
新版本的Chrome(90+)和Node.js(16+)已经修复了这个bug,直接升级环境后,原来的代码就能正常输出00而不是24。
内容的提问来源于stack exchange,提问作者fartwhif
相关产品推荐
相关产品推荐

