date_default_timezone_set() 函数用于设置脚本中所有日期时间函数使用的默认时区。设置时区是保证日期时间处理正确性的关键步骤。
bool date_default_timezone_set ( string $timezone_identifier )
| 参数 | 描述 | 必需 |
|---|---|---|
$timezone_identifier |
时区标识符字符串,如 'Asia/Shanghai'、'America/New_York'、'UTC' 等 | 是 |
<?php
// 获取当前默认时区
echo "当前时区: " . date_default_timezone_get() . "<br>";
// 设置时区为上海(东八区)
$result = date_default_timezone_set('Asia/Shanghai');
echo "设置结果: " . ($result ? '成功' : '失败') . "<br>";
echo "新时区: " . date_default_timezone_get() . "<br>";
// 显示当前时间
echo "当前时间: " . date('Y-m-d H:i:s') . "<br>";
echo "时区偏移: " . date('P') . "<br>"; // +08:00
// 显示时区信息
$timezone = new DateTimeZone(date_default_timezone_get());
$date = new DateTime();
echo "时区名称: " . $timezone->getName() . "<br>";
echo "UTC偏移: " . $timezone->getOffset($date) . " 秒";
?>
<?php
// 安全设置时区的函数
function safeSetTimezone($timezone) {
// 获取所有支持的时区
$validTimezones = timezone_identifiers_list();
if (in_array($timezone, $validTimezones)) {
$result = date_default_timezone_set($timezone);
if ($result) {
return "时区已成功设置为: {$timezone}";
} else {
return "时区设置失败: {$timezone}";
}
} else {
return "无效的时区标识符: {$timezone}";
}
}
// 测试不同的时区设置
$timezonesToTest = [
'Asia/Shanghai',
'America/New_York',
'Europe/London',
'UTC',
'Invalid/Timezone',
'EST', // 已弃用的时区缩写
];
foreach ($timezonesToTest as $tz) {
echo safeSetTimezone($tz) . "<br>";
}
// 显示当前时区信息
echo "<br>当前时区详细信息:<br>";
$currentTz = date_default_timezone_get();
$tzInfo = new DateTimeZone($currentTz);
$date = new DateTime();
$location = timezone_location_get($tzInfo);
echo "标识符: " . $currentTz . "<br>";
echo "偏移: " . $tzInfo->getOffset($date) / 3600 . " 小时<br>";
if ($location) {
echo "经纬度: {$location['latitude']}, {$location['longitude']}<br>";
echo "国家代码: {$location['country_code']}<br>";
echo "注释: {$location['comments']}<br>";
}
?>
<?php
// 设置默认时区
date_default_timezone_set('UTC');
echo "默认时区: " . date_default_timezone_get() . "<br><br>";
// 创建一个时间
$datetime = '2024-03-15 12:00:00';
echo "原始时间 (UTC): " . $datetime . "<br>";
// 转换到不同时区
$timezones = [
'America/New_York' => '纽约时间',
'Asia/Shanghai' => '上海时间',
'Europe/London' => '伦敦时间',
'Australia/Sydney' => '悉尼时间',
];
foreach ($timezones as $tz => $label) {
// 创建DateTime对象(使用UTC时区)
$date = new DateTime($datetime, new DateTimeZone('UTC'));
// 转换时区
$date->setTimezone(new DateTimeZone($tz));
echo "{$label} ({$tz}): " . $date->format('Y-m-d H:i:s') . "<br>";
}
// 显示不同时区当前时间
echo "<br>不同时区当前时间:<br>";
foreach ($timezones as $tz => $label) {
date_default_timezone_set($tz);
echo "{$label}: " . date('Y-m-d H:i:s') . " (GMT" . date('P') . ")<br>";
}
?>
<?php
/**
* 应用程序时区管理类
*/
class AppTimezone {
private static $applicationTimezone = 'UTC';
private static $userTimezone = null;
/**
* 初始化应用程序时区
*/
public static function init() {
// 从配置文件中读取时区设置
$configTimezone = self::getConfigTimezone();
// 设置应用程序默认时区
if (self::setTimezone($configTimezone)) {
self::$applicationTimezone = $configTimezone;
return true;
}
// 如果配置时区无效,使用UTC
self::setTimezone('UTC');
self::$applicationTimezone = 'UTC';
return false;
}
/**
* 设置时区
*/
public static function setTimezone($timezone) {
if (self::isValidTimezone($timezone)) {
return date_default_timezone_set($timezone);
}
return false;
}
/**
* 验证时区是否有效
*/
public static function isValidTimezone($timezone) {
return in_array($timezone, timezone_identifiers_list());
}
/**
* 获取配置中的时区(模拟)
*/
private static function getConfigTimezone() {
// 这里可以从配置文件、数据库或环境变量中读取
$config = [
'timezone' => 'Asia/Shanghai',
'auto_detect' => false,
];
return $config['timezone'];
}
/**
* 设置用户时区(用于个性化显示)
*/
public static function setUserTimezone($timezone) {
if (self::isValidTimezone($timezone)) {
self::$userTimezone = $timezone;
return true;
}
return false;
}
/**
* 将UTC时间转换为用户时区时间
*/
public static function toUserTime($utcTime) {
if (self::$userTimezone === null) {
return $utcTime; // 未设置用户时区,返回UTC时间
}
$date = new DateTime($utcTime, new DateTimeZone('UTC'));
$date->setTimezone(new DateTimeZone(self::$userTimezone));
return $date->format('Y-m-d H:i:s');
}
/**
* 将用户时区时间转换为UTC时间
*/
public static function toUTC($userTime) {
if (self::$userTimezone === null) {
return $userTime;
}
$date = new DateTime($userTime, new DateTimeZone(self::$userTimezone));
$date->setTimezone(new DateTimeZone('UTC'));
return $date->format('Y-m-d H:i:s');
}
/**
* 获取时区信息
*/
public static function getInfo($timezone = null) {
if ($timezone === null) {
$timezone = date_default_timezone_get();
}
if (!self::isValidTimezone($timezone)) {
return null;
}
$tz = new DateTimeZone($timezone);
$now = new DateTime('now', $tz);
return [
'identifier' => $timezone,
'name' => $tz->getName(),
'offset' => $tz->getOffset($now),
'formatted_offset' => $now->format('P'),
'is_dst' => $now->format('I'),
'abbreviation' => $now->format('T'),
'location' => timezone_location_get($tz),
];
}
}
// 使用示例
echo "应用程序时区管理演示:<br><br>";
// 初始化时区
AppTimezone::init();
echo "应用程序时区: " . date_default_timezone_get() . "<br>";
// 设置用户时区
AppTimezone::setUserTimezone('America/New_York');
echo "用户时区: America/New_York<br><br>";
// 时间转换示例
$utcTime = '2024-03-15 12:00:00';
$userTime = AppTimezone::toUserTime($utcTime);
$backToUTC = AppTimezone::toUTC($userTime);
echo "UTC时间: {$utcTime}<br>";
echo "用户时区时间: {$userTime}<br>";
echo "转换回UTC: {$backToUTC}<br><br>";
// 获取时区信息
$info = AppTimezone::getInfo('Asia/Shanghai');
echo "上海时区信息:<br>";
echo "标识符: " . $info['identifier'] . "<br>";
echo "偏移: " . $info['offset'] / 3600 . " 小时<br>";
echo "格式化偏移: " . $info['formatted_offset'] . "<br>";
echo "是否夏令时: " . ($info['is_dst'] ? '是' : '否') . "<br>";
echo "时区缩写: " . $info['abbreviation'] . "<br>";
?>
<?php
// 设置错误报告级别
error_reporting(E_ALL);
ini_set('display_errors', 1);
echo "时区错误处理演示:<br><br>";
// 1. 尝试设置无效时区
echo "测试1: 设置无效时区 'Invalid/Zone'<br>";
$result = @date_default_timezone_set('Invalid/Zone');
if ($result === false) {
echo "设置失败: 无效的时区标识符<br>";
}
// 2. 处理已弃用的时区缩写
echo "<br>测试2: 设置已弃用的时区缩写 'EST'<br>";
// 在PHP 7+中,这可能会产生警告
$result = @date_default_timezone_set('EST');
if ($result) {
echo "设置成功,但不推荐使用缩写<br>";
} else {
echo "设置失败,使用完整标识符如 'America/New_York'<br>";
}
// 3. 恢复有效时区
date_default_timezone_set('UTC');
echo "<br>已恢复时区为: " . date_default_timezone_get() . "<br>";
// 4. 使用try-catch处理DateTime异常
echo "<br>测试3: 处理DateTime异常<br>";
try {
// 创建带有时区的DateTime对象
$timezone = new DateTimeZone('Invalid/Timezone');
$date = new DateTime('now', $timezone);
echo "DateTime创建成功<br>";
} catch (Exception $e) {
echo "DateTime异常: " . $e->getMessage() . "<br>";
}
// 5. 检查时区变化对日期函数的影响
echo "<br>测试4: 时区对日期函数的影响<br>";
date_default_timezone_set('UTC');
$utcTime = date('Y-m-d H:i:s');
echo "UTC时间: " . $utcTime . "<br>";
date_default_timezone_set('Asia/Shanghai');
$shanghaiTime = date('Y-m-d H:i:s');
echo "上海时间: " . $shanghaiTime . "<br>";
// 计算时间差
$timeDiff = (strtotime($shanghaiTime) - strtotime($utcTime)) / 3600;
echo "时间差: " . $timeDiff . " 小时<br>";
// 6. 处理夏令时
echo "<br>测试5: 夏令时处理<br>";
date_default_timezone_set('America/New_York');
// 测试夏令时开始和结束的时间
$dates = [
'2024-03-10 01:59:59', // 夏令时开始前
'2024-03-10 03:00:00', // 夏令时开始后
'2024-11-03 01:59:59', // 夏令时结束前
'2024-11-03 02:00:00', // 夏令时结束后
];
foreach ($dates as $dateStr) {
$date = new DateTime($dateStr, new DateTimeZone('America/New_York'));
echo "{$dateStr}: " . $date->format('Y-m-d H:i:s T P') . "<br>";
}
?>
| 类型 | 格式 | 示例 | 说明 |
|---|---|---|---|
| 大陆/城市 | Continent/City | Asia/Shanghai America/New_York Europe/London |
推荐使用,包含完整的时区规则 |
| UTC偏移 | Etc/GMT±X | Etc/GMT+8 Etc/GMT-5 |
固定偏移时区,GMT+8表示东八区 |
| 缩写(已弃用) | EST, PST等 | EST, PST, CST | 不推荐使用,可能产生歧义 |
| 军事时区 | 字母 A-Z | UTC, GMT | 军事和航空领域使用 |
timezone_identifiers_list() 验证时区有效性| PHP版本 | 行为 | 说明 |
|---|---|---|
| PHP 5.1.0 | 引入此函数 | 开始提供时区设置功能 |
| PHP 5.3.0 | 时区处理改进 | 时区规则更加完善 |
| PHP 5.4.0 | 默认时区UTC | 未设置时区时默认使用UTC |
| PHP 5.5.10 | 时区缩写警告 | 开始警告使用已弃用的时区缩写 |
| PHP 7.0.0 | 更严格的时区验证 | 无效时区返回false |
date_default_timezone_set()Continent/City 格式的时区标识符timezone_identifiers_list() 中| 函数 | 描述 |
|---|---|
date_default_timezone_get() |
获取当前默认时区 |
timezone_identifiers_list() |
获取所有支持的时区标识符列表 |
timezone_open() |
创建新的DateTimeZone对象 |
ini_set('date.timezone') |
运行时设置php.ini中的时区配置 |
DateTime::setTimezone() |
设置DateTime对象的时区 |
DateTimeZone::getOffset() |
获取时区偏移 |