ThinkPHP 必须显式配置 default_timezone,因其启动时仅读取自身配置而不继承 PHP 系统时区;需在 config/app.php 中设置为 IANA 标识符(如 'Asia/Shanghai'),否则日志、缓存、date() 等时间行为错乱。

ThinkPHP 默认不自动同步系统时区,必须手动在配置中显式设置 default_timezone,否则日志、缓存、时间函数(如 date())可能错乱。
为什么 default_timezone 必须显式配置
ThinkPHP 启动时会调用 date_default_timezone_set(),但只读取配置项,不会 fallback 到系统 /etc/timezone 或 php.ini 的 date.timezone。即使 PHP 环境已设好时区,TP 仍按自己配置走。
- 常见错误现象:
echo date('Y-m-d H:i:s')输出比系统时间快/慢 8 小时,Log::write()时间戳对不上服务器日志 - 使用场景:部署到 Docker 容器、阿里云 ECS、或与 Nginx/Apache 系统时区不一致的环境
- 性能影响:无;只是单次函数调用,不影响请求耗时
在哪配?优先级顺序要清楚
ThinkPHP 6+ 的时区配置只认 app.php 中的 default_timezone,其他位置无效。
- 正确位置:
config/app.php文件里加一行:'default_timezone' => 'Asia/Shanghai' - 错误做法:改
php.ini里的date.timezone—— TP 不读它;在控制器里手动date_default_timezone_set()—— 每次请求都得重复设,且可能被中间件覆盖 - 注意兼容性:值必须是 IANA 时区标识符(如
Asia/Shanghai),不能写+08:00或GMT+8,否则抛出DateTimeZone::__construct(): Unknown or bad timezone
如何验证配置生效
别只看 phpinfo(),要测 TP 自己的时间行为。
立即学习“PHP免费学习笔记(深入)”;
- 在任意控制器里加:
var_dump(date_default_timezone_get(), date('Y-m-d H:i:s'));—— 两个输出应一致且符合预期 - 检查日志文件头时间戳是否与服务器
date命令输出一致 - 如果用了
think\facade\Cache,缓存键中的时间相关部分(如自定义过期逻辑)也会受此影响,需一并验证
最常被忽略的是:Docker 镜像里 PHP 时区设对了,但 TP 配置没改,结果日志全错位;还有人把 default_timezone 写成 timezone,字段名拼错导致静默失效。



















