PHP timezone_identifiers_list()函数

timezone_identifiers_list() 函数返回一个包含所有时区标识符的索引数组。这些标识符是遵循 Olson 时区数据库的标准时区名称,如 "America/New_York"、"Asia/Shanghai" 等。

这个函数是 PHP 中处理时区的基础函数之一,常用于创建时区选择器、验证时区有效性等场景。

语法

timezone_identifiers_list([int $timezoneGroup = DateTimeZone::ALL [, string $countryCode = null]]) : array

参数说明

参数 默认值 描述
timezoneGroup DateTimeZone::ALL

可选。 指定要返回的时区组。可以是以下常量之一:

  • DateTimeZone::AFRICA - 非洲时区
  • DateTimeZone::AMERICA - 美洲时区
  • DateTimeZone::ANTARCTICA - 南极洲时区
  • DateTimeZone::ARCTIC - 北极地区时区
  • DateTimeZone::ASIA - 亚洲时区
  • DateTimeZone::ATLANTIC - 大西洋时区
  • DateTimeZone::AUSTRALIA - 澳大利亚时区
  • DateTimeZone::EUROPE - 欧洲时区
  • DateTimeZone::INDIAN - 印度洋时区
  • DateTimeZone::PACIFIC - 太平洋时区
  • DateTimeZone::UTC - UTC 时区
  • DateTimeZone::ALL - 所有时区(默认)
  • DateTimeZone::ALL_WITH_BC - 包含公元前时区的所有时区
  • DateTimeZone::PER_COUNTRY - 按国家代码筛选的时区
countryCode null

可选。$timezoneGroup 设置为 DateTimeZone::PER_COUNTRY 时,指定要筛选的国家代码(ISO 3166-1 两位字母代码)。

例如:"US" 表示美国,"CN" 表示中国。

返回值

返回一个索引数组,包含符合筛选条件的时区标识符。如果未找到匹配的时区,返回空数组。

DateTimeZone 常量说明

常量 描述
DateTimeZone::AFRICA 1 非洲时区
DateTimeZone::AMERICA 2 美洲时区
DateTimeZone::ANTARCTICA 4 南极洲时区
DateTimeZone::ARCTIC 8 北极地区时区
DateTimeZone::ASIA 16 亚洲时区
DateTimeZone::ATLANTIC 32 大西洋时区
DateTimeZone::AUSTRALIA 64 澳大利亚时区
DateTimeZone::EUROPE 128 欧洲时区
DateTimeZone::INDIAN 256 印度洋时区
DateTimeZone::PACIFIC 512 太平洋时区
DateTimeZone::UTC 1024 UTC 时区
DateTimeZone::ALL 2047 所有时区(前10个的位或)
DateTimeZone::ALL_WITH_BC 4095 包含公元前时区的所有时区
DateTimeZone::PER_COUNTRY 4096 按国家代码筛选的时区

示例

示例 1:获取所有时区

<?php
// 获取所有时区标识符
$all_timezones = timezone_identifiers_list();

echo "总时区数: " . count($all_timezones) . "<br>";
echo "<h4>前10个时区:</h4>";
echo "<pre>";
for ($i = 0; $i < 10; $i++) {
    echo ($i + 1) . ". " . $all_timezones[$i] . "\n";
}
echo "...";

// 输出类似:
// 总时区数: 440
// 前10个时区:
// 1. Africa/Abidjan
// 2. Africa/Accra
// 3. Africa/Addis_Ababa
// 4. Africa/Algiers
// 5. Africa/Asmara
// 6. Africa/Asmera
// 7. Africa/Bamako
// 8. Africa/Bangui
// 9. Africa/Banjul
// 10. Africa/Bissau
?>

示例 2:按大洲获取时区

<?php
// 获取亚洲时区
$asia_timezones = timezone_identifiers_list(DateTimeZone::ASIA);

echo "亚洲时区数: " . count($asia_timezones) . "<br>";
echo "<h4>亚洲时区(前10个):</h4>";
echo "<pre>";
for ($i = 0; $i < 10; $i++) {
    if (isset($asia_timezones[$i])) {
        echo ($i + 1) . ". " . $asia_timezones[$i] . "\n";
    }
}
echo "...";

// 获取美洲时区
$america_timezones = timezone_identifiers_list(DateTimeZone::AMERICA);
echo "</pre>美洲时区数: " . count($america_timezones) . "<br>";

// 获取欧洲时区
$europe_timezones = timezone_identifiers_list(DateTimeZone::EUROPE);
echo "欧洲时区数: " . count($europe_timezones) . "<br>";

// 输出类似:
// 亚洲时区数: 111
// 亚洲时区(前10个):
// 1. Asia/Aden
// 2. Asia/Almaty
// 3. Asia/Amman
// 4. Asia/Anadyr
// 5. Asia/Aqtau
// 6. Asia/Aqtobe
// 7. Asia/Ashgabat
// 8. Asia/Atyrau
// 9. Asia/Baghdad
// 10. Asia/Bahrain
// ...
// 美洲时区数: 145
// 欧洲时区数: 114
?>

示例 3:获取指定国家的时区

<?php
// 获取美国的时区
$us_timezones = timezone_identifiers_list(DateTimeZone::PER_COUNTRY, "US");

echo "美国时区数: " . count($us_timezones) . "<br>";
echo "<h4>美国时区:</h4>";
echo "<pre>";
foreach ($us_timezones as $timezone) {
    echo "- " . $timezone . "\n";
}
echo "</pre>";

// 获取中国的时区
$cn_timezones = timezone_identifiers_list(DateTimeZone::PER_COUNTRY, "CN");
echo "中国时区数: " . count($cn_timezones) . "<br>";

// 获取英国的时区
$gb_timezones = timezone_identifiers_list(DateTimeZone::PER_COUNTRY, "GB");
echo "英国时区数: " . count($gb_timezones) . "<br>";

// 获取日本的时区
$jp_timezones = timezone_identifiers_list(DateTimeZone::PER_COUNTRY, "JP");
echo "日本时区数: " . count($jp_timezones) . "<br>";

// 输出类似:
// 美国时区数: 29
// 美国时区:
// - America/Adak
// - America/Anchorage
// - America/Boise
// - America/Chicago
// - America/Denver
// - America/Detroit
// - America/Indiana/Indianapolis
// - America/Indiana/Knox
// - America/Indiana/Marengo
// - America/Indiana/Petersburg
// - America/Indiana/Tell_City
// - America/Indiana/Vevay
// - America/Indiana/Vincennes
// - America/Indiana/Winamac
// - America/Juneau
// - America/Kentucky/Louisville
// - America/Kentucky/Monticello
// - America/Los_Angeles
// - America/Menominee
// - America/Metlakatla
// - America/New_York
// - America/Nome
// - America/North_Dakota/Beulah
// - America/North_Dakota/Center
// - America/North_Dakota/New_Salem
// - America/Phoenix
// - America/Sitka
// - America/Yakutat
// - Pacific/Honolulu
//
// 中国时区数: 5
// 英国时区数: 2
// 日本时区数: 4
?>

示例 4:验证时区有效性

<?php
// 验证时区是否有效
function isValidTimezone($timezone) {
    $all_timezones = timezone_identifiers_list();
    return in_array($timezone, $all_timezones);
}

// 测试
$test_timezones = [
    "America/New_York",
    "Asia/Shanghai",
    "Europe/London",
    "Invalid/Timezone",
    "Australia/Sydney",
    "Not/A/Real/Timezone"
];

echo "<h4>时区有效性验证:</h4>";
foreach ($test_timezones as $timezone) {
    if (isValidTimezone($timezone)) {
        echo "✓ {$timezone} 是有效的时区<br>";
    } else {
        echo "✗ {$timezone} 是无效的时区<br>";
    }
}

// 输出:
// ✓ America/New_York 是有效的时区
// ✓ Asia/Shanghai 是有效的时区
// ✓ Europe/London 是有效的时区
// ✗ Invalid/Timezone 是无效的时区
// ✓ Australia/Sydney 是有效的时区
// ✗ Not/A/Real/Timezone 是无效的时区
?>

示例 5:创建时区选择器

<?php
// 创建分组时区选择器
function createTimezoneSelect($name = "timezone", $selected = "UTC") {
    $groups = [
        'Africa' => DateTimeZone::AFRICA,
        'America' => DateTimeZone::AMERICA,
        'Antarctica' => DateTimeZone::ANTARCTICA,
        'Arctic' => DateTimeZone::ARCTIC,
        'Asia' => DateTimeZone::ASIA,
        'Atlantic' => DateTimeZone::ATLANTIC,
        'Australia' => DateTimeZone::AUSTRALIA,
        'Europe' => DateTimeZone::EUROPE,
        'Indian' => DateTimeZone::INDIAN,
        'Pacific' => DateTimeZone::PACIFIC,
        'UTC' => DateTimeZone::UTC
    ];

    $html = '<select name="' . $name . '" id="' . $name . '">';
    $html .= '<option value="">选择时区...</option>';

    foreach ($groups as $group_name => $group_id) {
        $timezones = timezone_identifiers_list($group_id);
        if (!empty($timezones)) {
            $html .= '<optgroup label="' . $group_name . '">';
            foreach ($timezones as $timezone) {
                $selected_attr = ($timezone == $selected) ? ' selected' : '';
                $html .= '<option value="' . $timezone . '"' . $selected_attr . '>' . $timezone . '</option>';
            }
            $html .= '</optgroup>';
        }
    }

    $html .= '</select>';
    return $html;
}

// 使用时区选择器
echo "<h4>时区选择器:</h4>";
echo createTimezoneSelect("user_timezone", "Asia/Shanghai");

// 输出 HTML 选择器
?>

示例 6:获取时区偏移量信息

<?php
// 获取时区及其偏移量
function getTimezonesWithOffsets() {
    $all_timezones = timezone_identifiers_list();
    $timezones_with_offset = [];

    foreach ($all_timezones as $timezone) {
        try {
            $tz = new DateTimeZone($timezone);
            $transitions = $tz->getTransitions(time(), time());
            if (!empty($transitions)) {
                $offset = $transitions[0]['offset'];
                $hours = $offset / 3600;
                $timezones_with_offset[] = [
                    'timezone' => $timezone,
                    'offset' => $offset,
                    'hours' => $hours,
                    'formatted' => 'UTC' . ($hours >= 0 ? '+' : '') . $hours
                ];
            }
        } catch (Exception $e) {
            // 跳过无效时区
            continue;
        }
    }

    // 按偏移量排序
    usort($timezones_with_offset, function($a, $b) {
        return $a['offset'] - $b['offset'];
    });

    return $timezones_with_offset;
}

// 获取并显示时区偏移量
$timezones = getTimezonesWithOffsets();
echo "<h4>时区偏移量(前20个):</h4>";
echo "<table border='1'>";
echo "<tr><th>时区</th><th>偏移量(小时)</th><th>偏移量(秒)</th></tr>";

for ($i = 0; $i < 20; $i++) {
    if (isset($timezones[$i])) {
        $tz = $timezones[$i];
        echo "<tr>";
        echo "<td>" . $tz['timezone'] . "</td>";
        echo "<td>" . $tz['formatted'] . "</td>";
        echo "<td>" . $tz['offset'] . "</td>";
        echo "</tr>";
    }
}
echo "</table>";

echo "<p>总时区数: " . count($timezones) . "</p>";

// 输出类似:
// 时区偏移量(前20个):
// 时区                       偏移量(小时)    偏移量(秒)
// Pacific/Midway             UTC-11           -39600
// Pacific/Niue               UTC-11           -39600
// Pacific/Pago_Pago          UTC-11           -39600
// America/Adak               UTC-10           -36000
// ... 更多
?>

示例 7:组合多个时区组

<?php
// 组合多个时区组
$multiple_groups = DateTimeZone::AMERICA | DateTimeZone::EUROPE | DateTimeZone::ASIA;
$combined_timezones = timezone_identifiers_list($multiple_groups);

echo "美洲、欧洲、亚洲时区总数: " . count($combined_timezones) . "<br>";
echo "<h4>组合时区(前10个):</h4>";
echo "<pre>";
for ($i = 0; $i < 10; $i++) {
    if (isset($combined_timezones[$i])) {
        echo ($i + 1) . ". " . $combined_timezones[$i] . "\n";
    }
}
echo "...";

// 计算各洲时区数
$america_count = count(timezone_identifiers_list(DateTimeZone::AMERICA));
$europe_count = count(timezone_identifiers_list(DateTimeZone::EUROPE));
$asia_count = count(timezone_identifiers_list(DateTimeZone::ASIA));

echo "</pre>";
echo "美洲时区数: " . $america_count . "<br>";
echo "欧洲时区数: " . $europe_count . "<br>";
echo "亚洲时区数: " . $asia_count . "<br>";

// 输出类似:
// 美洲、欧洲、亚洲时区总数: 370
// 组合时区(前10个):
// 1. Africa/Abidjan
// 2. Africa/Accra
// 3. Africa/Addis_Ababa
// ... 注意:由于位运算,可能包含其他时区
// 美洲时区数: 145
// 欧洲时区数: 114
// 亚洲时区数: 111
?>

常见时区参考

时区标识符 地区 描述
America/New_York 美国东部 纽约、华盛顿、迈阿密等
America/Chicago 美国中部 芝加哥、达拉斯、休斯顿等
America/Denver 美国山地 丹佛、凤凰城、盐湖城等
America/Los_Angeles 美国太平洋 洛杉矶、旧金山、西雅图等
Europe/London 英国 伦敦、都柏林、爱丁堡等
Europe/Paris 西欧 巴黎、柏林、罗马、马德里等
Asia/Shanghai 中国 北京时间,中国标准时间
Asia/Tokyo 日本 东京、大阪、名古屋等
Asia/Kolkata 印度 印度标准时间(加尔各答)
Australia/Sydney 澳大利亚东部 悉尼、墨尔本、布里斯班等
Pacific/Auckland 新西兰 奥克兰、惠灵顿等
UTC 全球 协调世界时

注意事项

  • 时区标识符遵循 Olson 时区数据库(也称为 tz database 或 IANA 时区数据库)
  • 时区名称的格式通常是 "大洲/城市" 或 "大洲/国家/城市"
  • 使用 DateTimeZone::PER_COUNTRY 时,必须提供有效的 ISO 3166-1 两位字母国家代码
  • 时区列表可能会随着时区数据库的更新而变化
  • 不同 PHP 版本返回的时区数量和具体标识符可能有所不同
  • 对于生产环境,建议缓存时区列表以提高性能

性能优化建议

场景 建议
频繁使用时区列表 缓存结果,避免重复调用 timezone_identifiers_list()
只需要特定大洲的时区 使用相应的 DateTimeZone 常量筛选,减少内存占用
创建时区选择器 按需加载时区,或使用 AJAX 分页加载
验证时区有效性 考虑使用 DateTimeZone::listIdentifiers() 替代
需要最新时区数据 定期更新系统的时区数据库

相关函数