PHP 中的时区
使用 DateTimeZone 和 date_default_timezone_set 处理多个时区。
PHP 中的时区 是 CoddyKit 上的免费 PHP Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 PHP Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 PHP Academy 课程共包含 4 节课。
时区为何重要
如果您的应用面向全球用户,时区处理就至关重要。PHP 使用支持时区的函数和类来正确处理转换。
- 始终在数据库中以 UTC 存储时间
- 仅在显示时转换为用户的本地时区
date_default_timezone_set()
请为所有日期函数设置默认时区:
<?php
// Set at the top of your script or in php.ini
date_default_timezone_set('Europe/Istanbul');
echo date('Y-m-d H:i:s'); // local Istanbul time
echo PHP_EOL;
date_default_timezone_set('UTC');
echo date('Y-m-d H:i:s'); // UTC time
// Or set in php.ini:
// date.timezone = "Europe/London"DateTimeZone 类
请创建时区对象,以便与 DateTime 一起使用:
<?php
$utc = new DateTimeZone('UTC');
$istanbul = new DateTimeZone('Europe/Istanbul');
$ny = new DateTimeZone('America/New_York');
$dt = new DateTime('now', $utc);
echo $dt->format('Y-m-d H:i:s T'); // UTC time在时区之间转换
请使用 setTimezone() 将 DateTime 转换为其他时区:
<?php
$utcTime = new DateTime('2024-05-27 12:00:00', new DateTimeZone('UTC'));
$istanbul = clone $utcTime;
$istanbul->setTimezone(new DateTimeZone('Europe/Istanbul'));
$newYork = clone $utcTime;
$newYork->setTimezone(new DateTimeZone('America/New_York'));
echo 'UTC: ' . $utcTime->format('H:i T') . PHP_EOL;
echo 'Istanbul: ' . $istanbul->format('H:i T') . PHP_EOL;
echo 'New York: ' . $newYork->format('H:i T') . PHP_EOL;getOffset() 和 DST
请获取 UTC 偏移量(以秒为单位),并检查是否处于 DST:
<?php
$tz = new DateTimeZone('America/New_York');
$dt = new DateTime('now', $tz);
$offset = $tz->getOffset($dt); // offset in seconds
$offsetHours = $offset / 3600;
echo 'Offset: ' . $offsetHours . 'h'; // e.g. -5 or -4 in DST
$transitions = $tz->getTransitions(
strtotime('2024-01-01'),
strtotime('2024-12-31')
);
echo 'DST changes in 2024: ' . count($transitions);以 UTC 存储,以本地时间显示
最佳实践:在数据库中存储 UTC,向用户显示本地时间:
<?php
// Store: always save as UTC
$createdAt = (new DateTimeImmutable('now', new DateTimeZone('UTC')))
->format('Y-m-d H:i:s');
// Display: convert to user's timezone
$userTz = new DateTimeZone($user['timezone'] ?? 'UTC');
$display = (new DateTime($createdAt, new DateTimeZone('UTC')))
->setTimezone($userTz)
->format('d M Y, H:i T');检测用户时区
请检测并存储用户的时区,以便用于显示:
// JavaScript: detect and send to PHP:
// const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
// fetch('/api/set-timezone', { method:'POST', body: tz });
<?php
// PHP: validate and store
$tz = $_POST['timezone'] ?? 'UTC';
$valid = in_array($tz, DateTimeZone::listIdentifiers());
if ($valid) {
$_SESSION['timezone'] = $tz;
setcookie('user_tz', $tz, time() + 365 * 86400);
}DateTimeZone::listIdentifiers()
请获取所有有效的时区标识符:
<?php
// All identifiers
$all = DateTimeZone::listIdentifiers();
echo count($all) . ' timezones available';
// Filter by region
$europe = DateTimeZone::listIdentifiers(DateTimeZone::EUROPE);
echo count($europe) . ' European timezones';
// Check if a timezone string is valid
function isValidTimezone(string $tz): bool {
return in_array($tz, DateTimeZone::listIdentifiers());
}
var_dump(isValidTimezone('Europe/Istanbul')); // true格式化时区偏移量
请格式化时区偏移量,以便用于显示和 API:
<?php
$dt = new DateTime('now', new DateTimeZone('America/Los_Angeles'));
echo $dt->format('P'); // +05:30 or -07:00
echo $dt->format('O'); // +0530 (no colon)
echo $dt->format('T'); // PST or PDT
echo $dt->format('e'); // America/Los_Angeles
echo $dt->format('Z'); // offset in secondsUnix 时间戳与时区无关
Unix 时间戳表示一个特定的时间点,与时区无关——请使用它们进行比较和计算:
<?php
// These represent the same moment:
$utc = new DateTime('2024-05-27 12:00:00', new DateTimeZone('UTC'));
$ist = new DateTime('2024-05-27 15:00:00', new DateTimeZone('Asia/Kolkata'));
echo $utc->getTimestamp(); // same timestamp
echo $ist->getTimestamp(); // same timestamp
var_dump($utc->getTimestamp() === $ist->getTimestamp()); // true带时区的 date_create
使用 date_create 和 date_timezone_set 进行过程式时区处理:
<?php
$dt = date_create('now', timezone_open('UTC'));
$tz = timezone_open('Europe/Istanbul');
date_timezone_set($dt, $tz);
echo date_format($dt, 'Y-m-d H:i:s T');
// Check transition info
$info = timezone_transitions_get($tz);
echo 'Current offset: ' . ($info[0]['offset'] / 3600) . 'h';快速检查
对于面向全球用户的应用,日期和时间应存储在数据库中的什么时区?
回顾:PHP 时区
时区要点:
- 使用
date_default_timezone_set()设置默认时区 - 将
DateTimeZone对象与 DateTime 一起使用 - 使用
setTimezone()在时区之间转换 - 始终在数据库中存储 UTC
- 使用
DateTimeZone::listIdentifiers()验证用户时区 - Unix 时间戳表示与时区无关的时间点
用 AI 导师学习 PHP — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 49
- 课程
- 195
常见问题解答
「PHP 中的时区」课时是免费的吗?
是的 — 「PHP 中的时区」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 PHP Academy 课程的其余内容,请升级到 CoddyKit PRO。 PHP Academy 课程共包含 4 节课。
「PHP 中的时区」这节课中我会学到什么?
使用 DateTimeZone 和 date_default_timezone_set 处理多个时区。 你通过在浏览器中直接运行的动手代码来练习 PHP Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 PHP Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 PHP Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「PHP 中的时区」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 PHP Academy 课中编写并运行代码吗?
能。每节 PHP Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。