date_timezone_get() 函数是 DateTime::getTimezone() 的过程化别名,用于获取 DateTime 对象的时区信息。
DateTime::getTimezone() 方法。
date_timezone_get(DateTimeInterface $object): DateTimeZone|false
| 参数 | 类型 | 描述 |
|---|---|---|
$object |
DateTimeInterface | 必需。DateTime或DateTimeImmutable对象 |
成功时返回 DateTimeZone 对象,失败时返回 false。
返回的 DateTimeZone 对象包含以下有用信息:
<?php
// 创建不同时区的DateTime对象
$timezones = [
'Asia/Shanghai',
'America/New_York',
'Europe/London',
'Australia/Sydney',
'UTC'
];
foreach ($timezones as $tz) {
$date = date_create('2023-12-25 14:30:45', new DateTimeZone($tz));
$timezone = date_timezone_get($date);
echo "时区: " . $timezone->getName() . "\n";
echo "位置: " . $timezone->getLocation()['country_code'] . " (" .
($timezone->getLocation()['comments'] ?? '无描述') . ")\n";
echo "偏移量: " . ($date->getOffset() / 3600) . " 小时\n";
echo "是否使用夏令时: " . ($date->format('I') ? '是' : '否') . "\n";
echo "当前时间: " . $date->format('Y-m-d H:i:s') . "\n";
echo "---\n";
}
?>
输出:
时区: Asia/Shanghai
位置: CN (无描述)
偏移量: 8 小时
是否使用夏令时: 否
当前时间: 2023-12-25 14:30:45
---
时区: America/New_York
位置: US (Eastern Time)
偏移量: -5 小时
是否使用夏令时: 否
当前时间: 2023-12-25 14:30:45
---
时区: Europe/London
位置: GB (无描述)
偏移量: 0 小时
是否使用夏令时: 否
当前时间: 2023-12-25 14:30:45
---
时区: Australia/Sydney
位置: AU (New South Wales (most areas))
偏移量: 11 小时
是否使用夏令时: 是
当前时间: 2023-12-25 14:30:45
---
时区: UTC
位置: ?? (无描述)
偏移量: 0 小时
是否使用夏令时: 否
当前时间: 2023-12-25 14:30:45
---
<?php
/**
* 时区转换器类
*/
class TimezoneConverter {
/**
* 将时间从一个时区转换到另一个时区
*/
public static function convertTimezone(DateTime $date, string $targetTimezone): DateTime {
$originalTimezone = date_timezone_get($date);
$convertedDate = clone $date;
date_timezone_set($convertedDate, new DateTimeZone($targetTimezone));
echo "原始时区: " . $originalTimezone->getName() . "\n";
echo "目标时区: " . $targetTimezone . "\n";
echo "原始时间: " . $date->format('Y-m-d H:i:s') . "\n";
echo "转换后时间: " . $convertedDate->format('Y-m-d H:i:s') . "\n";
echo "时间差: " . self::getTimezoneOffset($originalTimezone->getName(), $targetTimezone) . " 小时\n";
echo "---\n";
return $convertedDate;
}
/**
* 获取两个时区之间的偏移量差
*/
public static function getTimezoneOffset(string $fromTz, string $toTz): float {
$from = new DateTimeZone($fromTz);
$to = new DateTimeZone($toTz);
$now = new DateTime('now', $from);
$offsetFrom = $from->getOffset($now);
$offsetTo = $to->getOffset($now);
return ($offsetTo - $offsetFrom) / 3600;
}
/**
* 比较不同时区的同一时刻
*/
public static function compareGlobalTime(DateTime $referenceDate): array {
$globalTimes = [];
$popularTimezones = [
'Pacific/Honolulu',
'America/Los_Angeles',
'America/New_York',
'Europe/London',
'Europe/Paris',
'Asia/Dubai',
'Asia/Tokyo',
'Australia/Sydney'
];
foreach ($popularTimezones as $tz) {
$dateInTz = clone $referenceDate;
date_timezone_set($dateInTz, new DateTimeZone($tz));
$globalTimes[$tz] = $dateInTz->format('Y-m-d H:i:s');
}
return $globalTimes;
}
}
// 使用示例
$date = date_create('2023-12-25 14:30:45', new DateTimeZone('Asia/Shanghai'));
echo "示例1:时区转换\n";
TimezoneConverter::convertTimezone($date, 'America/New_York');
TimezoneConverter::convertTimezone($date, 'Europe/London');
TimezoneConverter::convertTimezone($date, 'Australia/Sydney');
echo "\n示例2:全球时间比较\n";
echo "北京时间 2023-12-25 14:30:45 在全球其他时区的对应时间:\n\n";
$globalTimes = TimezoneConverter::compareGlobalTime($date);
foreach ($globalTimes as $tz => $time) {
echo str_pad($tz, 25) . ": " . $time . "\n";
}
echo "\n示例3:获取当前时区信息\n";
$currentDate = date_create();
$currentTimezone = date_timezone_get($currentDate);
echo "当前时区: " . $currentTimezone->getName() . "\n";
echo "当前偏移量: " . ($currentDate->getOffset() / 3600) . " 小时\n";
// 显示时区的所有信息
echo "\n时区详细信息:\n";
$timezoneInfo = $currentTimezone->getLocation();
if ($timezoneInfo) {
echo "国家代码: " . ($timezoneInfo['country_code'] ?? '未知') . "\n";
echo "纬度: " . ($timezoneInfo['latitude'] ?? '未知') . "\n";
echo "经度: " . ($timezoneInfo['longitude'] ?? '未知') . "\n";
echo "注释: " . ($timezoneInfo['comments'] ?? '无') . "\n";
}
?>
输出:
示例1:时区转换
原始时区: Asia/Shanghai
目标时区: America/New_York
原始时间: 2023-12-25 14:30:45
转换后时间: 2023-12-25 01:30:45
时间差: -13 小时
---
原始时区: Asia/Shanghai
目标时区: Europe/London
原始时间: 2023-12-25 14:30:45
转换后时间: 2023-12-25 06:30:45
时间差: -8 小时
---
原始时区: Asia/Shanghai
目标时区: Australia/Sydney
原始时间: 2023-12-25 14:30:45
转换后时间: 2023-12-25 17:30:45
时间差: 3 小时
---
示例2:全球时间比较
北京时间 2023-12-25 14:30:45 在全球其他时区的对应时间:
Pacific/Honolulu : 2023-12-24 20:30:45
America/Los_Angeles : 2023-12-24 22:30:45
America/New_York : 2023-12-25 01:30:45
Europe/London : 2023-12-25 06:30:45
Europe/Paris : 2023-12-25 07:30:45
Asia/Dubai : 2023-12-25 10:30:45
Asia/Tokyo : 2023-12-25 15:30:45
Australia/Sydney : 2023-12-25 17:30:45
示例3:获取当前时区信息
当前时区: Asia/Shanghai
当前偏移量: 8 小时
时区详细信息:
国家代码: CN
纬度: 31.23333
经度: 121.46666
注释: 无
<?php
/**
* 国际化时间显示系统
*/
class InternationalTimeDisplay {
private $userTimezone;
private $serverTimezone;
public function __construct(string $userTimezone = 'UTC') {
$this->userTimezone = new DateTimeZone($userTimezone);
$this->serverTimezone = new DateTimeZone(date_default_timezone_get());
}
/**
* 设置用户时区
*/
public function setUserTimezone(string $timezone): void {
$this->userTimezone = new DateTimeZone($timezone);
}
/**
* 获取用户友好的时间显示
*/
public function displayTime(DateTime $serverTime, bool $showTimezone = true): string {
// 转换到用户时区
$userTime = clone $serverTime;
date_timezone_set($userTime, $this->userTimezone);
// 获取时区信息
$serverTimezone = date_timezone_get($serverTime);
$userTimezone = date_timezone_get($userTime);
// 格式化显示
$format = 'Y年m月d日 H:i:s';
$display = $userTime->format($format);
if ($showTimezone) {
$display .= ' ' . $this->getTimezoneAbbreviation($userTimezone);
}
// 添加相对时间信息
$relative = $this->getRelativeTime($serverTime);
return $display . " (" . $relative . ")";
}
/**
* 获取时区缩写
*/
private function getTimezoneAbbreviation(DateTimeZone $timezone): string {
$now = new DateTime('now', $timezone);
return $now->format('T');
}
/**
* 获取相对时间描述
*/
private function getRelativeTime(DateTime $time): string {
$now = new DateTime('now', $this->serverTimezone);
$diff = $now->diff($time);
if ($diff->days === 0) {
if ($diff->h === 0 && $diff->i < 5) {
return '刚刚';
} elseif ($diff->h === 0) {
return $diff->i . '分钟前';
} else {
return $diff->h . '小时前';
}
} elseif ($diff->days === 1) {
return $time->format('H:i') . ' (昨天)';
} elseif ($diff->days < 7) {
return $time->format('m-d H:i');
} else {
return $time->format('Y-m-d');
}
}
/**
* 批量转换时间到不同时区
*/
public function convertToMultipleTimezones(DateTime $time, array $timezones): array {
$results = [];
foreach ($timezones as $tz) {
$converted = clone $time;
$timezoneObj = new DateTimeZone($tz);
date_timezone_set($converted, $timezoneObj);
$results[$tz] = [
'time' => $converted->format('Y-m-d H:i:s'),
'timezone' => $timezoneObj->getName(),
'offset' => $converted->getOffset() / 3600,
'abbreviation' => $converted->format('T')
];
}
return $results;
}
/**
* 获取时区信息摘要
*/
public function getTimezoneSummary(DateTimeZone $timezone): array {
$now = new DateTime('now', $timezone);
return [
'name' => $timezone->getName(),
'abbreviation' => $now->format('T'),
'offset' => $now->getOffset() / 3600,
'dst' => (bool)$now->format('I'),
'location' => $timezone->getLocation()
];
}
}
// 使用示例
$display = new InternationalTimeDisplay('Asia/Shanghai');
// 创建一些时间
$times = [
'now' => new DateTime(),
'1_hour_ago' => new DateTime('-1 hour'),
'tomorrow' => new DateTime('+1 day'),
'next_week' => new DateTime('+1 week'),
'last_year' => new DateTime('-1 year')
];
echo "国际化时间显示系统演示\n\n";
// 显示不同时间的用户友好格式
foreach ($times as $name => $time) {
echo $name . ": " . $display->displayTime($time) . "\n";
}
echo "\n批量时区转换演示:\n";
$serverTime = new DateTime('2023-12-25 14:30:45', new DateTimeZone('UTC'));
$timezones = ['Asia/Shanghai', 'America/New_York', 'Europe/London', 'Australia/Sydney'];
$convertedTimes = $display->convertToMultipleTimezones($serverTime, $timezones);
foreach ($convertedTimes as $tz => $info) {
echo $info['timezone'] . " (" . $info['abbreviation'] . "): " .
$info['time'] . " (UTC" . ($info['offset'] >= 0 ? '+' : '') . $info['offset'] . ")\n";
}
echo "\n时区信息摘要:\n";
$currentTimezone = date_timezone_get(new DateTime());
$summary = $display->getTimezoneSummary($currentTimezone);
echo "名称: " . $summary['name'] . "\n";
echo "缩写: " . $summary['abbreviation'] . "\n";
echo "偏移量: UTC" . ($summary['offset'] >= 0 ? '+' : '') . $summary['offset'] . "\n";
echo "夏令时: " . ($summary['dst'] ? '是' : '否') . "\n";
if ($summary['location']) {
echo "位置: " . ($summary['location']['country_code'] ?? '未知') . " - " .
($summary['location']['comments'] ?? '无描述') . "\n";
}
?>
输出:
国际化时间显示系统演示
now: 2023年12月25日 22:30:45 CST (刚刚)
1_hour_ago: 2023年12月25日 21:30:45 CST (1小时前)
tomorrow: 2023年12月26日 22:30:45 CST (明天 22:30)
next_week: 2024年01月01日 22:30:45 CST (01-01 22:30)
last_year: 2022年12月25日 22:30:45 CST (2022-12-25)
批量时区转换演示:
Asia/Shanghai (CST): 2023-12-25 22:30:45 (UTC+8)
America/New_York (EST): 2023-12-25 09:30:45 (UTC-5)
Europe/London (GMT): 2023-12-25 14:30:45 (UTC+0)
Australia/Sydney (AEDT): 2023-12-26 01:30:45 (UTC+11)
时区信息摘要:
名称: Asia/Shanghai
缩写: CST
偏移量: UTC+8
夏令时: 否
位置: CN - 无描述
推荐使用面向对象风格的 DateTime::getTimezone() 方法,代码更清晰:
<?php
// 创建DateTime对象并指定时区
$date = new DateTime('2023-12-25 14:30:45', new DateTimeZone('Asia/Shanghai'));
// 获取时区对象
$timezone = $date->getTimezone();
echo "时区名称: " . $timezone->getName() . "\n";
echo "时区缩写: " . $date->format('T') . "\n";
echo "偏移量: " . ($date->getOffset() / 3600) . " 小时\n";
// 链式调用示例
$info = (new DateTime('now', new DateTimeZone('America/New_York')))
->getTimezone()
->getName();
echo "链式调用获取时区: " . $info . "\n";
// DateTimeImmutable 示例
$immutableDate = new DateTimeImmutable('2023-06-21 12:00:00', new DateTimeZone('Europe/London'));
$immutableTimezone = $immutableDate->getTimezone();
echo "\nDateTimeImmutable示例:\n";
echo "日期: " . $immutableDate->format('Y-m-d H:i:s') . "\n";
echo "时区: " . $immutableTimezone->getName() . "\n";
// 获取所有可用时区
echo "\n常用时区列表:\n";
$timezones = DateTimeZone::listIdentifiers();
$popularTimezones = array_filter($timezones, function($tz) {
return in_array($tz, [
'Asia/Shanghai', 'Asia/Tokyo', 'Asia/Dubai',
'Europe/London', 'Europe/Paris', 'Europe/Berlin',
'America/New_York', 'America/Los_Angeles', 'America/Chicago',
'Australia/Sydney', 'Australia/Melbourne',
'UTC', 'GMT'
]);
});
foreach ($popularTimezones as $tz) {
$tempDate = new DateTime('now', new DateTimeZone($tz));
echo str_pad($tz, 25) . ": UTC" .
($tempDate->getOffset() >= 0 ? '+' : '') .
($tempDate->getOffset() / 3600) . "\n";
}
?>
输出:
时区名称: Asia/Shanghai
时区缩写: CST
偏移量: 8 小时
链式调用获取时区: America/New_York
DateTimeImmutable示例:
日期: 2023-06-21 12:00:00
时区: Europe/London
常用时区列表:
Asia/Shanghai : UTC+8
Asia/Tokyo : UTC+9
Asia/Dubai : UTC+4
Europe/London : UTC+0
Europe/Paris : UTC+1
Europe/Berlin : UTC+1
America/New_York : UTC-5
America/Los_Angeles : UTC-8
America/Chicago : UTC-6
Australia/Sydney : UTC+11
Australia/Melbourne : UTC+11
UTC : UTC+0
GMT : UTC+0
DateTime::getTimezone() 方法,代码更易读且支持链式调用。
<?php
// 错误:创建DateTime对象时未指定时区
$date = new DateTime('2023-12-25 14:30:45');
// 使用服务器的默认时区,可能导致不一致
// 正确:明确指定时区
$date = new DateTime('2023-12-25 14:30:45', new DateTimeZone('Asia/Shanghai'));
// 正确:使用date_default_timezone_set()
date_default_timezone_set('Asia/Shanghai');
$date = new DateTime('2023-12-25 14:30:45');
?>
<?php
// 错误:直接修改时间而不是时区
$date = new DateTime('2023-12-25 14:30:45', new DateTimeZone('Asia/Shanghai'));
$date->modify('+8 hours'); // 这不是时区转换!
// 正确:使用setTimezone方法
$date->setTimezone(new DateTimeZone('UTC'));
echo "转换后: " . $date->format('Y-m-d H:i:s') . "\n";
?>
<?php
// 夏令时期间的时间转换需要特别注意
$date = new DateTime('2023-03-12 02:30:00', new DateTimeZone('America/New_York'));
echo "纽约时间: " . $date->format('Y-m-d H:i:s T') . "\n";
// 转换为UTC
$date->setTimezone(new DateTimeZone('UTC'));
echo "UTC时间: " . $date->format('Y-m-d H:i:s T') . "\n";
// 注意:某些时间在夏令时转换时可能不存在或重复
$invalidTime = new DateTime('2023-03-12 02:30:00', new DateTimeZone('America/New_York'));
// 这个时间在美国夏令时开始时不存在(02:00直接跳到03:00)
?>
DateTimeZone 对象可以重复使用,无需重复创建。DateTimeZone 对象可以提高性能。date_default_timezone_get() 的返回值。date_timezone_set()设置DateTime对象的时区
DateTime::getTimezone()面向对象风格的获取时区方法
DateTime::setTimezone()设置DateTime对象的时区
date_default_timezone_get()获取脚本默认时区
date_default_timezone_set()设置脚本默认时区
timezone_identifiers_list()获取所有可用的时区标识符