You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用IntlDateFormatter时年末日期大写Y显示下一年的原因

PHP IntlDateFormatter年末日期年份异常问题解析

问题背景

需求为每月末以塞尔维亚语拉丁字母格式输出月份全称与完整年份(如“Januar 2024”),但在PHP7.4与PHP8.2环境(默认时区Europe/Berlin)下,处理2024年12月30日、31日时,输出结果为decembar 2025(月份正确但年份变为下一年),仅12月29日及之前日期能输出正确的decembar 2024。

测试代码示例:

$period = new DateTimeImmutable('2024-12-31');
$format = new IntlDateFormatter('sr-Latn', IntlDateFormatter::NONE, IntlDateFormatter::NONE, NULL, IntlDateFormatter::GREGORIAN, "MMMM Y");
$label = datefmt_format($format, $period);
echo $label;

异常原因解析

核心问题出在格式字符串中Y与y格式符的本质区别:

  • Y:代表基于周的年份(遵循ISO 8601标准),规则是一年的第一周必须包含该年的1月4日(或该年的第一个周四)。2024年12月30日、31日在ISO周历中属于2025年的第1周,因此使用Y时会输出2025。
  • y:代表公历日历年份,即日期所属的自然年份,不受周历规则影响。

而月份MMMM始终基于公历日历月份计算,因此即使周年份跳转到2025,月份仍显示12月,最终出现decembar 2025的矛盾结果。

时区Europe/Berlin的作用是确保日期的时间戳对应到本地时间,从而正确计算ISO周所属的年份,这也是仅特定日期出现异常的原因——这两天的本地时间恰好落在下一年的周范围内。

解决方案

将格式字符串中的"MMMM Y"修改为"MMMM y",即可输出正确的日历年份:

$format = new IntlDateFormatter('sr-Latn', IntlDateFormatter::NONE, IntlDateFormatter::NONE, NULL, IntlDateFormatter::GREGORIAN, "MMMM y");

内容的提问来源于stack exchange,提问作者Igor Vidic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 02:21:11