php时区设置失败主因是date.timezone未配置或被覆盖;应修改php.ini中date.timezone为合法iana时区名(如"asia/shanghai"),重启服务,并用date_default_timezone_get()与ini_get('date.timezone')核对实际生效值。

PHP 时区设置失败,最常见原因是 date.timezone 未正确配置或被运行时函数覆盖。 直接改 php.ini 并重启服务,90% 的问题就解决了;剩下的是代码里用 date_default_timezone_set() 调用出错或时机不对。
检查当前生效的时区配置
不要只看 php.ini 文件,PHP 实际加载的是运行时生效的配置。执行以下代码确认:
echo date_default_timezone_get() . "\n";
print_r(ini_get('date.timezone'));
如果输出是 UTC 或空字符串,说明配置未生效。注意:date_default_timezone_get() 返回的是当前有效时区,而 ini_get('date.timezone') 只返回 php.ini 中的原始值——两者不一致,说明被代码覆盖了。
修改 php.ini 中的 date.timezone
找到你实际在用的 php.ini(用 php --ini 或 phpinfo() 确认路径),取消注释并设为合法时区名:
立即学习“PHP免费学习笔记(深入)”;
- ✅ 正确写法:
date.timezone = "Asia/Shanghai"(必须用双引号包裹,且是 IANA 时区名) - ❌ 错误写法:
date.timezone = Asia/Shanghai(无引号,PHP 5.4+ 会解析失败) - ❌ 错误写法:
date.timezone = "GMT+8"(不是合法时区名,date_default_timezone_set()也不接受这种格式) - 重启 Web 服务器(Apache/Nginx)或 PHP-FPM,否则修改不生效
date_default_timezone_set() 调用失败的典型场景
这个函数只在脚本运行期起作用,但极易因调用位置或参数错误失效:
- 在
require/include其他文件之后才调用 → 已有日期函数(如date())提前触发警告,时区被设为UTC - 传入非法字符串,例如:
date_default_timezone_set("China/Beijing")(IANA 数据库中不存在该名称) - 在 CLI 模式下调用成功,但 Web 模式下被
php.ini的值覆盖(CLI 和 Web 通常使用不同配置文件) - 框架(如 Laravel、ThinkPHP)可能在引导阶段已调用过一次,重复调用无效,且不会报错
时区错误引发的实际问题与验证方式
时区没设对,最直接的表现不是报错,而是时间值“看起来对、其实错”:
-
date('Y-m-d H:i:s')返回的时间比系统本地时间快/慢 8 小时(尤其在日志、缓存键、JWT 过期时间中埋雷) -
strtotime('tomorrow')在跨夏令时地区可能偏差一天 - MySQL 的
NOW()和 PHPdate()返回时间不一致,导致 WHERE 条件错判 - 用
new DateTime()不传时区参数时,默认用date.timezone;若为空,则触发E_WARNING并回退到UTC
真正难排查的是:错误发生在依赖链深处(比如某个 Composer 包内部调用了 date()),而你的代码里根本没碰时间函数。











