HOWTO · PHP

在 PHP 中获取时区

本教程演示如何使用 PHP 中的内置函数获取时区。

本页内容

PHP 会为依赖活动默认时区的日期和时间操作使用当前默认时区。调用 date_default_timezone_get() 可读取该设置;向 date_default_timezone_set() 传入有效的时区标识可更改它。若特定值或对象需要自己的时区,请使用 DateTimeZone;若要构建供用户选择的列表,请使用 DateTimeZone::listIdentifiers()。

地名与时区标识是不同类型的输入:PHP 不会根据街道地址或城市名称推断时区标识。对于用户个人的时区偏好,应保存经过验证的标识,并在需要时应用;在长期运行的应用程序中,不要为了单个用户的请求更改共享默认值。

获取当前默认时区

默认时区是当前为依赖该设置的 PHP 日期和时间函数配置的时区。它可能来自应用程序、PHP 配置或运行环境,因此不要假定每个安装环境都使用 UTC。date_default_timezone_get() 会以标识形式返回当前生效的设置,例如 UTC 或 America/New_York。

运行以下示例:

本节中的代码以及显示的标签或输出仍为英文。

<?php
$defaultTimezone = date_default_timezone_get();
echo $defaultTimezone, PHP_EOL;

需要检查当前配置时,可以使用返回的标识。如果应用程序要求使用特定时区,请明确设置,不要依赖特定机器上的默认配置。

设置默认时区

向 date_default_timezone_set() 传入受支持的标识,即可更改当前生效的默认时区。设置成功时,函数返回 true;如果不接受该标识,则返回 false。之后读取一次设置值,以确认当前生效的时区。此更改会影响后续依赖 PHP 默认时区的日期和时间操作,但不会更改已经携带自身时区的 DateTime 对象。

示例在设置成功时输出当前生效的时区标识;如果标识未被接受,则会输出英文提示语 The time zone identifier was not accepted.。

本节中的代码以及显示的标签或输出仍为英文。

<?php
$identifier = 'America/New_York';
$set = date_default_timezone_set($identifier);

if ($set) {
    echo date_default_timezone_get(), PHP_EOL;
} else {
    echo "The time zone identifier was not accepted.", PHP_EOL;
}

如果 Web 请求需要采用用户选择的时区,请先验证提交的标识,并考虑将明确指定的时区传给相关日期/时间对象,而不是更改整个进程的默认值。这样可以避免无关操作受到请求专属状态的影响。

根据地点获取时区

DateTimeZone 接受的是时区标识,而不是地理地址。例如,Europe/London 是 PHP 可用于创建时区对象的标识。城市的时区可能因历史变化或政策调整而改变,因此应从可靠的选项中选择标识,不要试图从任意地点文本推导时区。

本节中的代码以及显示的标签或输出仍为英文。

<?php
$identifier = 'Europe/London';
$timezone = new DateTimeZone($identifier);
echo $timezone->getName(), PHP_EOL;

该对象表示传入的标识,可传给接受 DateTimeZone 的日期/时间 API。如果标识来自用户输入,请在创建对象前将其与可用标识进行核对,以便应用程序妥善处理不受支持的输入。

从 DateTime 对象获取时区

DateTime 对象的时区可能与 PHP 当前生效的默认时区不同。对该对象调用 getTimezone() 可取得它的 DateTimeZone,再调用 getName() 读取标识。这样可以查明该值关联的时区;date_default_timezone_get() 则用于读取依赖默认设置的操作当前采用的时区。

本节中的代码以及显示的标签或输出仍为英文。

<?php
$date = new DateTime('2024-01-15 09:30:00', new DateTimeZone('Asia/Karachi'));
$timezone = $date->getTimezone();
echo $timezone->getName(), PHP_EOL;

创建对象时传入时区,可以明确指定应如何解释该对象中的时间。这样也能避免将对象自身的时区与之后更改的默认设置混淆。

列出可用的时区标识

使用 DateTimeZone::listIdentifiers() 获取可用于时区选择器的标识。完整列表可能很长,因此应通过可搜索或其他便于访问的控件展示,而不是把每个条目都打印在页面上。保存标识作为值即可;也可以另加供读者查看的显示名称。

本节中的代码以及显示的标签或输出仍为英文。

<?php
$identifiers = DateTimeZone::listIdentifiers();
foreach (array_slice($identifiers, 0, 5) as $identifier) {
    echo $identifier, PHP_EOL;
}

为使示例简洁,此示例限制了显示的条目数。构建完整的选择数据时,应移除切片操作,并保留 PHP 返回的标识作为控件提交的值。可用集合可能取决于 PHP 安装环境所使用的时区数据库,因此应在运行时填充列表,不要维护未经验证的硬编码列表。