PHP7.1中MessageFormatter年末日期格式化错误的原因及修复方案?
问题原因分析
哈哈,这个坑我之前踩过!本质上是把ISO周年份和我们日常用的公历年搞混了~
先给你说清楚ISO周的规则:国际标准ISO 8601规定,每年的第一周是包含1月4日的那一周(换个更直观的说法:包含当年第一个星期四的周)。这就导致每年12月末的几天,可能会被划分到下一年的第一周——比如2019年12月29日是周日,这一天属于2020年的第一ISO周(因为2020年1月1日是周三,第一周覆盖了2019年12月30日到2020年1月5日),所以对应的ISO周年份就是2020年。而2018年12月31日是周一,属于2018年的最后一周,所以没出现这个问题。
再看你的代码:
MessageFormatter里的YYYY(大写Y)对应的是ISO周年份,不是我们日常说的公历年(公历年要用小写的yyyy);strftime里的%G同样代表ISO周年份,而%Y才是常规的公历年。
这就是为什么12月末的日期会显示下一年的原因——不是代码bug,是格式符用错啦!
修复方法
针对两种场景分别调整格式符即可:
1. 修复MessageFormatter代码
把格式串里的YYYY改成小写的yyyy:
$dateFormatted = \MessageFormatter::formatMessage( 'en_US', "{0, date, d MMMM yyyy}", [new \DateTime()] ); var_dump($dateFormatted); // 现在会输出正确的公历年,比如29 December 2019
2. 修复strftime代码
把%G替换成%Y:
// 错误示例(输出ISO周年份) echo strftime("%d %B %G", strtotime("2019-12-29")); // 会输出29 December 2020 // 正确示例(输出公历年) echo strftime("%d %B %Y", strtotime("2019-12-29")); // 输出29 December 2019
内容的提问来源于stack exchange,提问作者Jakupov
相关产品推荐
相关产品推荐

