php时区未设或设错会导致日志时间偏差,应统一设为asia/shanghai:web端在入口文件首行调用date_default_timezone_set(),cli端修改php.ini中date.timezone,框架优先配config,db连接需额外执行set time_zone。

PHP date_default_timezone_set() 未设置或设错
日志里时间比实际快/慢几小时,八成是 PHP 没设时区,或设成了 UTC、Europe/London 这类非本地时区。PHP 默认用 UTC,不报错但时间全偏移。
确认当前设置:
php -r "echo date_default_timezone_get();"如果输出
UTC 或空字符串,就坐实了问题。
- 在入口文件(如
index.php)最顶部第一行加:date_default_timezone_set('Asia/Shanghai'); - 不要用
PRC—— 已废弃,PHP 8.1+ 会警告;必须用 IANA 标准名,中国大陆统一用Asia/Shanghai - 若用框架(Laravel、ThinkPHP),优先改配置文件(如 Laravel 的
config/app.php中'timezone' => 'Asia/Shanghai'),而非手动调用函数
Web 服务器与 PHP CLI 时区不一致
网页访问日志时间正常,但 php artisan schedule:run 或 crontab 调用的脚本日志仍错——这是 CLI SAPI 没单独设时区。
CLI 和 Web(如 Apache/FPM)是两套 PHP 配置,php.ini 可能有两份:
- 查 CLI 的 ini 文件:
php --ini→ 看 “Loaded Configuration File” 路径 - 编辑该
php.ini,取消注释并修改:date.timezone = Asia/Shanghai - 重启 cron 或重载 crond 不必要,PHP CLI 每次启动都读 ini,改完即生效
错误地在运行中多次调用 date_default_timezone_set()
有些老代码在多个地方重复设时区,比如在函数里、循环里、异常处理分支里都调一次。PHP 允许,但容易被覆盖或干扰扩展行为(如某些 ORM 时间字段自动转换)。
立即学习“PHP免费学习笔记(深入)”;
- 全局只设一次:放在应用初始化最早可执行位置(如框架
bootstrap.php或public/index.php头部) - 避免在类方法、闭包、条件分支里再调用 —— 尤其别写成
if (!date_default_timezone_get()) { ... }这种“兜底”,PHP 7.4+ 后date_default_timezone_get()永远返回字符串,不会为 false - 检查是否有扩展(如
intl)或 Composer 包(如monolog/monolog)内部依赖时区,它们以date_default_timezone_get()为准,乱设会导致日志时间分裂
数据库连接层也受 PHP 时区影响
MySQL 的 NOW()、PostgreSQL 的 CURRENT_TIMESTAMP 是服务端时间,但 PHP 的 DateTime 对象插入前若没显式指定时区,可能被隐式转成 UTC 再存,导致查出来的时间和日志对不上。
- 统一源头:确保 PHP 层所有
new DateTime()都带时区,例如:new DateTime('now', new DateTimeZone('Asia/Shanghai')) - MySQL 用户变量
time_zone别依赖 PHP 设置 —— 它是独立的,建议在 PDO 连接后执行:$pdo->exec("SET time_zone = '+08:00'"); - Log 库(如 Monolog)若用
RotatingFileHandler,其文件名含日期,也依赖date(),所以必须先设好时区,否则轮转逻辑出错











