PHP IntlDateFormatter 为何把 2025 年格式化为 2026 年?
数据阿明
原因
问题出在 IntlDateFormatter 使用的 ICU 日期格式模式:Y 表示周年(week-based year),不是日历年。周年按周历规则计算,所以年底的日期可能已属于下一周年,格式化结果会显示 2026。DateTime 对象仍是 2025-12-29,两者并不矛盾。
模式中的 i 也不是 ICU 的分钟符号。ICU 用小写 m 表示分钟,s 表示秒。PHP date() 的格式符不能直接用于 ICU 格式模式。
修正格式模式
将 Y 改为 y,输出日历年;将 i 改为 m,输出分钟:
$pattern = 'd.MMMM.y H:mm:ss';
$dtime_format = new IntlDateFormatter(
'de_DE',
IntlDateFormatter::FULL,
IntlDateFormatter::NONE,
'Europe/Berlin',
IntlDateFormatter::FULL,
$pattern
);
$date_test = new DateTime('2025-12-29 08:00:00 Europe/Berlin');
echo $dtime_format->format($date_test);
模式中各符号的含义:
d:日MMMM:完整月份名称y:日历年H:24 小时制小时mm:分钟ss:秒
对于原问题中的日期,使用 y 后会显示年份 2025。如果业务上需要周年,可以保留 Y,但要确认这符合预期。
注意事项
IntlDateFormatter 使用 ICU 格式规则,不适用 PHP date() 的格式符。遇到格式异常时,核对符号所属的格式体系,并区分 y(日历年)和 Y(周年)。
备注:内容仅供参考。
