php的date()函数默认输出英文月份/星期,因其格式化符不读取locale设置;可靠方案是使用intldateformatter(需intl扩展)或手写中文映射数组,避免依赖setlocale()和已废弃的strftime()。

date() 函数输出英文月份/星期怎么办
PHP 的 date() 函数默认依赖系统 locale,但它的格式化符(如 F、D、M)**根本不读 locale 设置**,只输出固定英文。这不是 bug,是设计如此——它压根没打算本地化。
常见错误现象:date('F j, Y') 永远返回 January 1, 2024,哪怕你已执行 setlocale(LC_TIME, 'zh_CN.UTF-8') 也没用。
- 别试图用
setlocale()+date()组合解决这个问题 - 真正起作用的是
strftime()(但注意它在 Windows 和新版 PHP 中行为不一致) - 更可靠的做法:自己映射,或换用
IntlDateFormatter
strftime() 在不同系统上输出中文不稳定
strftime() 理论上支持 locale,但它在 Windows 下基本不可用(尤其中文 locale 名常为 Chinese_China.936,和 Linux 的 zh_CN.UTF-8 不兼容),且 PHP 8.1+ 已标记为废弃。
使用场景:仅限旧项目维护,且能确保运行环境 locale 配置完整、编码匹配。
立即学习“PHP免费学习笔记(深入)”;
- Linux 下需确认
locale -a | grep zh_CN能列出zh_CN.utf8 - 调用前必须用
setlocale(LC_TIME, 'zh_CN.UTF-8'),且返回值非 false 才算生效 - 格式符要用
%B(全月名)、%A(星期全名),date()的F/l在这里无效 - 示例:
setlocale(LC_TIME, 'zh_CN.UTF-8'); echo strftime('%Y年%B%d日', time());
推荐方案:用 IntlDateFormatter 做真正可靠的中文化
IntlDateFormatter 是 ICU 库驱动的,跨平台、不依赖系统 locale,PHP 5.3+ 内置(需启用 intl 扩展)。它是目前最干净、可维护性最高的解法。
性能影响几乎可忽略;兼容性取决于是否开了 intl——线上环境建议检查 extension_loaded('intl')。
- 构造时指定语言标签:
new IntlDateFormatter('zh_CN', ...) - 月份/星期自动转中文,无需映射表
- 支持自定义模式,比如
yyyy年MM月dd日 EEEE→2024年06月12日 星期三 - 简短示例:
$fmt = new IntlDateFormatter('zh_CN', IntlDateFormatter::FULL, IntlDateFormatter::NONE, 'Asia/Shanghai', IntlDateFormatter::GREGORIAN, 'yyyy年M月d日 EEEE');<br>echo $fmt->format(time());
简单项目不想引入 intl 扩展?手写映射最实在
如果服务器不能装 intl,又不想碰 strftime() 的坑,直接用数组映射是最可控的。虽然要写几行,但逻辑透明、零依赖、无兼容风险。
容易踩的坑:只映射月份忘了星期,或大小写不一致(date('D') 返回小写 mon,date('l') 才是首字母大写 Monday)。
- 映射
date('M')→ 中文缩写(Jan→1月),用 12 元素索引数组最省事 - 映射
date('l')→ 中文星期(注意date('w')返回数字 0–6 更稳妥,避免语言差异) - 别硬套“今天是
date('l')”,先date('w')取数字再查表,避免英文字符串比较 - 示例片段:
$weekdays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];<br>$w = date('w');<br>echo '今天是' . $weekdays[$w];
IntlDateFormatter,得先看 intl 扩展有没有;而手写映射看着土,反而在 Docker 容器或老旧 CentOS 上最省心。











