strftime() 在 PHP 8.1 中已被弃用,PHP 9.0 将彻底移除,生产环境必须迁移;唯一能替代其本地化能力的是 IntlDateFormatter::formatObject(),前提是 intl 扩展已启用且 locale 字符串有效。

strftime() 在 PHP 8.1 中已被标记为 #[\Deprecated],PHP 9.0 将彻底移除。现在不能安全使用——不是“还能用但不推荐”,而是“已进入淘汰倒计时,生产环境必须迁移”。
strftime() 报错或返回 false 的常见原因
- PHP 版本 ≥ 8.1 且 error_reporting 包含
E_DEPRECATED:调用时触发弃用警告(Deprecated: strftime(): Calling strftime() is deprecated) - 某些容器/云环境(如 Alpine + PHP 8.2+)已提前禁用该函数,直接报
Call to undefined function strftime() -
%e、%R、%T等格式符在 Windows 或 musl libc 系统上本就不支持,弃用后更无兼容兜底 -
setlocale(LC_TIME, ...)设置失效或被忽略,导致输出始终为英文(尤其在 Docker 中)
替代方案必须用 IntlDateFormatter::formatObject()
date() 和 DateTime::format() 无法替代 strftime() 的核心能力:本地化月份/星期名称(如 “janvier”、“四月”、“木曜日”)。它们只支持固定语言的英文格式。
IntlDateFormatter::formatObject() 是唯一能真正继承 strftime() 行为的替代:
- 不依赖系统
setlocale(),行为可预测 - 支持 BCP 47 locale(
'fr'、'zh_Hans_CN'、'ja_JP') - ICU 模式与
strftime()格式一一映射(但写法不同)
// ✅ 正确迁移示例:strftime("%d %B %Y", $ts) → IntlDateFormatter
$dt = new DateTime('@' . $ts); // 或 new DateTime('2020-03-15')
$formatted = IntlDateFormatter::formatObject($dt, 'd MMMM y', 'fr');
// 输出:"15 mars 2020"(不是 "15 March 2020")
注意 ICU 模式对应关系:
立即学习“PHP免费学习笔记(深入)”;
-
%d→d(不是dd,否则补零) -
%B→MMMM(全称),%b→MMM -
%Y→y(yyyy也可,但y更健壮) -
%A→EEEE,%a→EEE
容易被忽略的硬性前提
-
intl扩展必须启用:运行php -m | grep intl确认;Ubuntu/Debian 需apt install php-intl,Alpine 需apk add php82-intl(版本号按实际调整) - locale 字符串必须有效:
'zh'可用,但'ch'或'cn'会静默失败,返回英文 -
DateTime对象必须带时区:隐式使用date_default_timezone_set()不可靠,建议显式传new DateTimeZone('Asia/Shanghai') - 不要混用
setlocale():它对IntlDateFormatter完全无效,只会干扰其他逻辑
真正卡住人的地方往往不是写法,而是 intl 扩展缺失或 locale 名称拼错——这两个问题不解决,换什么函数都白搭。



















