php 8.5.5 必须显式配置 iana 标准时区(如 date.timezone = asia/shanghai),且需同步设置 mysql default-time-zone = '+08:00',并确保 cli/web 环境 php.ini 一致、重启服务生效,否则时间函数报错或静默错误。

PHP 8.5.5 必须显式设置 date.timezone,否则所有时间函数(date()、strtotime()、new DateTime())都会触发 Warning: date(): It is not safe to rely on the system's timezone settings,甚至在某些场景下静默返回错误结果。
php.ini 中必须配 date.timezone = Asia/Shanghai
PHP 8.5.5 不再容忍该配置为空或被注释——它不会 fallback 到系统时区,也不会读取 /etc/timezone 或 TZ 环境变量。
- 用
php --ini找到 CLI 加载的 php.ini 路径;用phpinfo()查 Web 环境实际加载的配置文件路径(二者常不一致) - 编辑对应 php.ini,在
[Date]段落下添加或取消注释:date.timezone = Asia/Shanghai - 严禁写成
date.timezone = GMT+8、date.timezone = PRC或date.timezone = CST—— 这些不是 IANA 标准标识符,PHP 8.5+ 会静默忽略 - 改完后必须重启 PHP-FPM / Apache / Nginx,仅 reload 不生效
date_default_timezone_set() 必须在第一行调用
即使 php.ini 已配,CLI 脚本、队列任务、Swoole Worker 等场景仍可能绕过 ini 配置,运行时覆盖更可靠,但时机极其关键。
- 放在入口文件(如
public/index.php或index.php)**第一个非注释 PHP 行**,早于任何require、include、框架自动加载 - 调用后立刻校验:
var_dump(date_default_timezone_get());—— 输出必须是字符串"Asia/Shanghai",而非false或空 - 传参必须是字符串,且严格匹配:大小写敏感(
Asia/shanghai失败),拼写不能错(Asia/ShangHai失败) - 不要在中间件、模型构造、循环里重复调用 —— 后续调用无效,且可能干扰已初始化的组件(如日志时间戳)
MySQL 时区不同步会导致写入错乱
PHP 设了 Asia/Shanghai,但 MySQL 还按 SYSTEM(常为 UTC)解析 NOW() 或 DATETIME 字段,结果就是“显示对、存错”。
- 进 MySQL 执行:
SELECT @@global.time_zone, @@session.time_zone;—— 若返回SYSTEM,需确认系统时区是否真为+08:00 - 推荐在
my.cnf的[mysqld]段落加:default-time-zone = '+08:00',然后重启 MySQL - 避免在每次 PDO/mysqli 连接后执行
SET time_zone = '+08:00'—— 连接池复用时容易失效,且无法保证事务内一致性 - 存储层优先用
int存time()返回值,天然规避时区格式化问题;若必须存字符串,确保 PHP 和 MySQL 时区完全对齐
DateTime 构造不传时区等于埋雷
new DateTime('2024-01-01') 和 new DateTime('2024-01-01', new DateTimeZone('Asia/Shanghai')) 在默认时区为 UTC 时行为完全不同:前者把字符串当 UTC 解析,后者明确按东八区解释。
- 从数据库读
DATETIME字段(无时区信息)时,务必显式传时区:new DateTime($row['created_at'], new DateTimeZone('Asia/Shanghai')) - 用
DateTimeImmutable替代DateTime,避免意外修改原始对象时区上下文 - ThinkPHP 的
config/app.php中default_timezone仅影响框架内部封装(如Time::now()),不影响原生date()或DateTime,不能替代date_default_timezone_set() - 输出格式注意:
$dt->format('Y-m-d H:i:s')不带偏移,易掩盖混淆;$dt->format('c')带+08:00,可验证时区是否真正生效
最易被忽略的是 CLI 和 Web 环境加载了不同 php.ini,导致本地测试正常、上线报错;其次是 MySQL 时区未同步,表面时间没错,数据库记录却偏移 8 小时——这种错位往往在数据导出、跨库比对时才暴露。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











