date() 函数会根据当前 PHP 配置的默认时区输出时间,默认时区可以通过 date_default_timezone_set() 设置,或者从 php.ini 中读取。
gmdate() 函数总是返回格林威治标准时间(UTC),不会受默认时区设置影响。
<?php
// 设置默认时区为上海时间(东八区)
date_default_timezone_set('Asia/Shanghai');
echo "date() 输出时间:" . date('Y-m-d H:i:s') . "\n"; // 输出本地时间,比如 2025-05-22 16:00:00
echo "gmdate() 输出时间:" . gmdate('Y-m-d H:i:s') . "\n"; // 输出 UTC 时间,比如 2025-05-22 08:00:00
?>
这段代码展示了 date() 与 gmdate() 输出的差异,使用时必须注意这一点。
如果你的应用逻辑中既需要使用本地时间,也需要使用 UTC 时间,那么你必须明确区分两者,不能混淆。
保持时间戳统一
采用时间戳(time() 或 strtotime())作为时间的统一表示形式,避免直接操作格式化后的时间字符串。
转换时区时使用 DateTime 类
PHP 的 DateTime 和 DateTimeZone 类提供了更强大和灵活的时区转换能力。
<?php
// 获取当前 UTC 时间
$utcTime = new DateTime('now', new DateTimeZone('UTC'));
// 将 UTC 时间转换为上海时间
$localTime = clone $utcTime;
$localTime->setTimezone(new DateTimeZone('Asia/Shanghai'));
echo "UTC 时间:" . $utcTime->format('Y-m-d H:i:s') . "\n";
echo "上海时间:" . $localTime->format('Y-m-d H:i:s') . "\n";
?>
这样不仅避免了使用 gmdate() 与 date() 混淆,还能清晰地控制和转换时区。
不要把 gmdate() 生成的字符串当作本地时间直接使用。
如果你需要生成一个 UTC 时间的时间戳或格式化字符串,可以放心使用 gmdate()。
如果想要格式化某个时间戳为本地时间,使用 date() 函数并设置正确的时区。
<?php
function formatTimeWithTimezone(int $timestamp, string $timezone = 'Asia/Shanghai'): string {
$dt = new DateTime("@$timestamp"); // 使用时间戳创建 DateTime 对象,默认为 UTC
$dt->setTimezone(new DateTimeZone($timezone)); // 设置目标时区
return $dt->format('Y-m-d H:i:s T'); // 输出带时区缩写的时间
}
$nowTimestamp = time();
echo "当前时间(上海):" . formatTimeWithTimezone($nowTimestamp, 'Asia/Shanghai') . "\n";
echo "当前时间(UTC):" . formatTimeWithTimezone($nowTimestamp, 'UTC') . "\n";
?>
这样可以确保输出时间是准确且带有时区信息的,避免因混淆而出错。
gmdate() 返回的是 UTC 时间,date() 返回的是当前默认时区时间。
在处理时间时,建议使用时间戳作为统一时间格式。
使用 DateTime 和 DateTimeZone 类更灵活地处理时区转换。
绝不可随意混用 gmdate() 和 date(),避免时区混淆带来的错误。
掌握这些要点后,你的 PHP 时间处理将更加稳健,避免在输出时间时产生时区混淆问题。