date_default_timezone_set 是 PHP 设置脚本默认时区的唯一可靠方式,必须在脚本开头调用,参数须为 IANA 时区标识符(如 'Asia/Shanghai'),不可用 'GMT+8' 等非标准值,且不与 DateTimeZone 实例互影响。

date_default_timezone_set 是 PHP 设置脚本默认时区的唯一可靠方式,直接改 php.ini 虽然一劳永逸,但多数共享主机或容器环境不允许,所以运行时调用这个函数是实际项目中最常用、最可控的做法。
为什么必须在脚本开头调用 date_default_timezone_set
PHP 的日期时间函数(如 date()、strtotime()、new DateTime())都依赖默认时区。如果没设,PHP 会先查 date.timezone 配置项;没配就报 Warning: date(): It is not safe to rely on the system's timezone settings,而且返回时间可能错 8 小时(比如服务器在 UTC,你在中国却按 UTC 解析)。
- 必须在首次调用任何时间函数前执行,否则警告仍会触发
- 不能放在条件分支里(比如
if ($env === 'prod')),因为一旦漏掉,后续所有时间逻辑都不可靠 - 推荐放在入口文件(如
index.php或框架的 bootstrap 文件)最顶部,一行搞定:date_default_timezone_set('Asia/Shanghai');
date_default_timezone_set 的参数必须是 IANA 时区标识符
不能填 'GMT+8'、'CST' 或 'China' —— 这些不是合法值,调用会返回 false,且不报错,极易被忽略。
- 正确写法只有类似
'Asia/Shanghai'、'America/New_York'、'Europe/London'这类 IANA 标准名 - 可用
date_default_timezone_list()查看当前 PHP 支持的全部时区列表 - 中国大陆统一用
'Asia/Shanghai'(不是'Asia/Beijing',后者不存在) - Docker 环境中即使系统
tzdata已装,PHP 仍需显式调用该函数,不能依赖系统时区
与 DateTimeZone 实例混用时的常见陷阱
显式创建 DateTime 对象时传了 DateTimeZone,不代表全局时区就变了——date_default_timezone_set 和对象级时区是两套机制,互不影响。
立即学习“PHP免费学习笔记(深入)”;
- 下面代码输出仍是服务器本地时间(或默认时区时间),不是上海时间:
$dt = new DateTime('now', new DateTimeZone('Asia/Shanghai')); - 但
date('Y-m-d H:i:s')仍走date_default_timezone_set设的值 - 混合使用时,建议统一以
DateTime+ 显式DateTimeZone为主,避免依赖全局时区,尤其在微服务或跨时区业务中 - 若必须用
date(),确保date_default_timezone_set已生效且不可被覆盖
真正麻烦的不是设不设,而是设错位置、设错值、或者以为设了就万事大吉——尤其是当 date() 和 DateTime 混用,又没做时区转换验证时,时间差几个小时的问题往往在线上静默发生,很难复现。



















