php date() 时间错误主因是时区未设,默认按utc计算;应统一在php.ini设date.timezone=asia/shanghai,或脚本开头调date_default_timezone_set(‘asia/shanghai’),框架项目则改对应配置项。

PHP date() 输出时间不对,八成是时区没设
PHP 默认不设时区,date()、strtotime()、new DateTime() 全按 UTC 算——你本地显示“2024-05-10 02:00”,实际可能是北京时间的 10:00,差了八小时。
最直接的修复方式是在脚本开头加:date_default_timezone_set('Asia/Shanghai');
- 必须在所有时间函数调用前执行,放
date()后面就无效 - 值不能写错:
'PRC'已废弃,'Asia/Shanghai'是当前推荐写法 - 如果用 composer 加载框架(如 laravel),别在入口文件硬写,优先改配置(见下一条)
Laravel / symfony 项目里改时区别碰 date_default_timezone_set()
框架自己管时区,硬设会和 config/app.php 的 'timezone' 冲突,导致 carbon 和原生函数行为不一致。
- Laravel:只改
config/app.php里的'timezone' => 'Asia/Shanghai',别额外调date_default_timezone_set() - Symfony:在
.env设APP_TIMEZONE=Asia/Shanghai,或配framework.yaml中的default_timezone - 验证是否生效:
php -r "echo date_default_timezone_get();",不是框架配置项,而是 PHP 运行时实际生效的值
DateTime 构造时不指定时区,等于埋雷
new DateTime('2024-05-10') 看似简单,但没传时区参数时,它会用 date_default_timezone_get() 的结果——而这个值可能被前面某段代码悄悄改过,也可能根本没设(回退到 UTC)。
立即学习“PHP免费学习笔记(深入)”;
- 安全写法是显式传时区:
new DateTime('2024-05-10', new DateTimeZone('Asia/Shanghai')) - 数据库存时间戳(int)或 UTC 字符串时,构造
DateTime一定要带new DateTimeZone('UTC'),否则解析出来的时间对象内部时区是错的 - 用
DateTime::createFromFormat()也一样:第三个参数必须是DateTimeZone实例,不能是字符串
CLI 和 Web 请求时区可能不一致
你在浏览器里 date() 显示正确,但命令行跑 php artisan schedule:run 却差八小时?因为 CLI 模式读的是 php.ini 的 date.timezone,Web 模式可能被 ini_set() 或框架覆盖了。
- 查 CLI 当前时区:
php -r "echo date_default_timezone_get();" - 查 Web 当前时区:写个
phpinfo();页面看Date小节 - 统一方案:在系统级
php.ini里设date.timezone = Asia/Shanghai,比脚本里反复设更可靠 - 注意 docker 环境:基础镜像常默认 UTC,得在
Dockerfile里ENV TZ=Asia/Shanghai并RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
时区问题难调试,是因为它不报错、不抛异常,只默默给你一个“看起来合理”的错误时间。真正要盯住的不是函数怎么写,而是每个时间对象诞生那一刻,它的 DateTimeZone 是什么、date_default_timezone_get() 返回什么、PHP 进程启动时从哪读的配置。