PAYATHON 2026

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(周年)。

备注:内容仅供参考。