为什么Safari中Intl.DateTimeFormat会随年份返回不同月份?
问题原因与解决方案
这是Safari 11.1(WebKit 13605.1.33.1.4)版本中Intl.DateTimeFormat的已知实现bug,根源在于当时WebKit引擎使用的ICU(Unicode国际化组件)版本较低,且对夏令时规则变更的处理存在逻辑错误。
具体细节
你代码里的new Date(2006, 3)按JS规范应该代表2006年4月1日(因为Date的月份参数是0索引:0=1月,3=4月),但Safari 11.1的Intl实现错误地将其解析为3月(Mar),而2007年的同月份却能正确返回Apr。这是因为2007年美国调整了夏令时规则(从原4月第一个周日启动,改为3月第二个周日),旧版本WebKit的ICU库没有正确兼容新旧规则的年份差异,导致格式化时出现月份偏移。
Chrome使用的V8引擎搭配了更新的ICU版本,已经修复了这个规则兼容问题,所以能得到符合预期的结果。
解决办法
- 升级浏览器:最简单的方式是把Safari升级到12或更高版本,后续的WebKit更新彻底修复了这个Intl.DateTimeFormat的bug。
- 自定义格式化函数:如果无法升级浏览器,可以绕过Intl API,自己实现月份格式化:
// 英文短月份数组 const enShortMonths = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; function getShortMonth(date) { return enShortMonths[date.getMonth()]; } // 调用示例 getShortMonth(new Date(2006, 3)); // 正确返回 "Apr" - 强制使用UTC时区:如果业务场景允许忽略本地时区,可以指定
timeZone: 'UTC'来避免夏令时规则的影响:new Intl.DateTimeFormat('en-US', { month: 'short', timeZone: 'UTC' }).format(new Date(2006, 3)); // 返回 "Apr"
内容的提问来源于stack exchange,提问作者mark
相关产品推荐
相关产品推荐

