PHP timezone_name_from_abbr()函数

timezone_name_from_abbr() 函数根据时区缩写返回时区名称。这个函数可以根据时区缩写、偏移量(以秒为单位)和夏令时标志来查找匹配的时区。

注意:由于一个时区缩写可能对应多个时区(如 "CST" 可以表示中国标准时间或美国中部标准时间),因此可能需要结合偏移量和夏令时标志来确定具体的时区。

语法

timezone_name_from_abbr(string $abbr [, int $utcOffset = -1 [, int $isDST = -1]]) : string|false

参数说明

参数 默认值 描述
abbr

必需。 时区缩写。

utcOffset -1

可选。 以秒为单位的 UTC 偏移量。例如,对于 UTC+8,偏移量为 28800(8 * 3600)。

默认值 -1 表示不限制偏移量。

isDST -1

可选。 夏令时标志。

1 表示夏令时,0 表示非夏令时,-1 表示不限制。

返回值

成功时返回时区名称(字符串),失败时返回 false

示例

示例 1:基本用法 - 仅使用时区缩写

<?php
// 仅使用时区缩写查找
echo "EST: " . timezone_name_from_abbr("EST") . "<br>";
echo "PST: " . timezone_name_from_abbr("PST") . "<br>";
echo "GMT: " . timezone_name_from_abbr("GMT") . "<br>";
echo "CST: " . timezone_name_from_abbr("CST") . "<br>"; // 注意:CST 有多个匹配
echo "JST: " . timezone_name_from_abbr("JST") . "<br>";
echo "AEST: " . timezone_name_from_abbr("AEST") . "<br>";

// 输出类似:
// EST: America/New_York
// PST: America/Los_Angeles
// GMT: Europe/London
// CST: America/Chicago
// JST: Asia/Tokyo
// AEST: Australia/Sydney
?>

示例 2:结合偏移量查找

<?php
// 结合偏移量查找,解决缩写歧义
echo "CST (无偏移量): " . timezone_name_from_abbr("CST") . "<br>";
echo "CST (偏移量 -21600): " . timezone_name_from_abbr("CST", -21600) . "<br>"; // UTC-6
echo "CST (偏移量 28800): " . timezone_name_from_abbr("CST", 28800) . "<br>";   // UTC+8

// 测试不同偏移量
echo "<br>测试不同偏移量的 EST:<br>";
echo "EST (-18000): " . timezone_name_from_abbr("EST", -18000) . "<br>";  // UTC-5
echo "EST (-14400): " . timezone_name_from_abbr("EST", -14400) . "<br>";  // UTC-4 (EDT)

// 测试无效偏移量
$result = timezone_name_from_abbr("EST", 99999);
echo "EST (无效偏移量 99999): " . ($result === false ? 'false' : $result) . "<br>";

// 输出类似:
// CST (无偏移量): America/Chicago
// CST (偏移量 -21600): America/Chicago
// CST (偏移量 28800): Asia/Shanghai
//
// 测试不同偏移量的 EST:
// EST (-18000): America/New_York
// EST (-14400): false
// EST (无效偏移量 99999): false
?>

示例 3:结合夏令时标志查找

<?php
// 结合夏令时标志查找
echo "<h4>EST 的不同组合:</h4>";
echo "EST (无限制): " . timezone_name_from_abbr("EST") . "<br>";
echo "EST (非夏令时): " . timezone_name_from_abbr("EST", -1, 0) . "<br>";
echo "EST (夏令时): " . timezone_name_from_abbr("EST", -1, 1) . "<br>";

echo "<h4>EDT 的不同组合:</h4>";
echo "EDT (无限制): " . timezone_name_from_abbr("EDT") . "<br>";
echo "EDT (非夏令时): " . timezone_name_from_abbr("EDT", -1, 0) . "<br>";
echo "EDT (夏令时): " . timezone_name_from_abbr("EDT", -1, 1) . "<br>";

echo "<h4>PDT 的不同组合:</h4>";
echo "PDT (无限制): " . timezone_name_from_abbr("PDT") . "<br>";
echo "PDT (偏移量 -25200, 夏令时): " . timezone_name_from_abbr("PDT", -25200, 1) . "<br>"; // UTC-7

// 输出类似:
// EST 的不同组合:
// EST (无限制): America/New_York
// EST (非夏令时): America/New_York
// EST (夏令时): false
//
// EDT 的不同组合:
// EDT (无限制): America/New_York
// EDT (非夏令时): false
// EDT (夏令时): America/New_York
//
// PDT 的不同组合:
// PDT (无限制): America/Los_Angeles
// PDT (偏移量 -25200, 夏令时): America/Los_Angeles
?>

示例 4:处理缩写歧义

<?php
// 处理有歧义的时区缩写
function getPossibleTimezonesFromAbbr($abbr, $offset = -1, $isDST = -1) {
    $abbreviations = timezone_abbreviations_list();
    $abbr = strtolower($abbr);

    $results = [];
    if (isset($abbreviations[$abbr])) {
        foreach ($abbreviations[$abbr] as $info) {
            // 检查偏移量
            if ($offset != -1 && $info['offset'] != $offset) {
                continue;
            }
            // 检查夏令时
            if ($isDST != -1 && $info['dst'] != ($isDST == 1)) {
                continue;
            }

            $results[] = [
                'timezone_id' => $info['timezone_id'],
                'offset' => $info['offset'],
                'dst' => $info['dst']
            ];
        }
    }

    return $results;
}

// 测试 CST 的所有可能时区
echo "<h4>CST 的所有可能时区:</h4>";
$cst_timezones = getPossibleTimezonesFromAbbr("CST");
foreach ($cst_timezones as $tz) {
    $hours = $tz['offset'] / 3600;
    echo "时区: " . $tz['timezone_id'] .
         ", 偏移量: " . $tz['offset'] . " 秒 (UTC" . ($hours >= 0 ? '+' : '') . $hours . ")" .
         ", 夏令时: " . ($tz['dst'] ? '是' : '否') . "<br>";
}

echo "<h4>CST (偏移量 28800) 的时区:</h4>";
$cst_utc8 = getPossibleTimezonesFromAbbr("CST", 28800);
if (empty($cst_utc8)) {
    echo "无匹配时区<br>";
} else {
    foreach ($cst_utc8 as $tz) {
        echo "时区: " . $tz['timezone_id'] . "<br>";
    }
}

// 输出类似:
// CST 的所有可能时区:
// 时区: America/Chicago, 偏移量: -21600 秒 (UTC-6), 夏令时: 否
// 时区: America/Havana, 偏移量: -18000 秒 (UTC-5), 夏令时: 否
// 时区: Asia/Shanghai, 偏移量: 28800 秒 (UTC+8), 夏令时: 否
// 时区: Asia/Taipei, 偏移量: 28800 秒 (UTC+8), 夏令时: 否
// ... 更多
//
// CST (偏移量 28800) 的时区:
// 时区: Asia/Shanghai
// 时区: Asia/Taipei
?>

示例 5:从偏移量获取时区名称

<?php
// 从偏移量获取时区名称(不使用缩写)
function getTimezoneFromOffset($offset_hours, $isDST = -1) {
    $offset_seconds = $offset_hours * 3600;

    // 尝试常见的缩写
    $common_abbrs = [
        'EST' => -5, 'EDT' => -4,
        'CST' => -6, 'CDT' => -5,
        'MST' => -7, 'MDT' => -6,
        'PST' => -8, 'PDT' => -7,
        'GMT' => 0, 'BST' => 1,
        'CET' => 1, 'CEST' => 2,
        'IST' => 5.5, 'JST' => 9,
        'CST' => 8, 'AEST' => 10, 'AEDT' => 11
    ];

    foreach ($common_abbrs as $abbr => $hours) {
        if ($hours == $offset_hours) {
            $result = timezone_name_from_abbr($abbr, $offset_seconds, $isDST);
            if ($result !== false) {
                return $result;
            }
        }
    }

    // 如果没有匹配的缩写,尝试使用空字符串
    $result = timezone_name_from_abbr("", $offset_seconds, $isDST);
    if ($result !== false) {
        return $result;
    }

    return false;
}

// 测试
echo "<h4>从偏移量获取时区:</h4>";
$offsets = [-8, -5, 0, 8, 9.5, 12];
foreach ($offsets as $offset) {
    $timezone = getTimezoneFromOffset($offset);
    echo "UTC" . ($offset >= 0 ? '+' : '') . $offset . ": " .
         ($timezone ? $timezone : '未找到') . "<br>";
}

// 输出类似:
// 从偏移量获取时区:
// UTC-8: America/Los_Angeles
// UTC-5: America/New_York
// UTC+0: Europe/London
// UTC+8: Asia/Shanghai
// UTC+9.5: Australia/Adelaide
// UTC+12: Pacific/Auckland
?>

示例 6:处理用户输入的时区缩写

<?php
// 安全地处理用户输入的时区缩写
function sanitizeTimezoneFromUserInput($input, $offset_hours = null) {
    // 清理输入
    $abbr = strtoupper(trim($input));

    if (empty($abbr)) {
        return ['success' => false, 'message' => '时区缩写不能为空'];
    }

    // 如果提供了偏移量
    $offset_seconds = ($offset_hours !== null) ? $offset_hours * 3600 : -1;

    // 尝试获取时区名称
    $timezone_name = timezone_name_from_abbr($abbr, $offset_seconds);

    if ($timezone_name === false) {
        // 尝试不区分大小写
        $timezone_name = timezone_name_from_abbr(strtolower($abbr), $offset_seconds);
    }

    if ($timezone_name !== false) {
        return [
            'success' => true,
            'timezone' => $timezone_name,
            'abbr' => $abbr,
            'offset_hours' => $offset_hours
        ];
    } else {
        return [
            'success' => false,
            'message' => "无法找到时区缩写 '{$abbr}'" .
                        ($offset_hours !== null ? " (偏移量 UTC" .
                        ($offset_hours >= 0 ? '+' : '') . $offset_hours . ")" : "")
        ];
    }
}

// 测试用户输入
$test_inputs = [
    ['est', null],
    ['pst', -8],
    ['cst', 8],
    ['jst', null],
    ['invalid', null],
    ['', null]
];

foreach ($test_inputs as $input) {
    list($abbr, $offset) = $input;
    $result = sanitizeTimezoneFromUserInput($abbr, $offset);

    echo "<strong>输入:</strong> '{$abbr}'" .
         ($offset !== null ? " (偏移量 UTC" . ($offset >= 0 ? '+' : '') . $offset . ")" : "") .
         "<br>";

    if ($result['success']) {
        echo "<span style='color: green;'>✓ 找到时区: " . $result['timezone'] . "</span>";
    } else {
        echo "<span style='color: red;'>✗ " . $result['message'] . "</span>";
    }
    echo "<br><br>";
}

// 输出类似:
// 输入: 'est' (偏移量 UTC-5)
// ✓ 找到时区: America/New_York
//
// 输入: 'pst' (偏移量 UTC-8)
// ✓ 找到时区: America/Los_Angeles
//
// 输入: 'cst' (偏移量 UTC+8)
// ✓ 找到时区: Asia/Shanghai
//
// 输入: 'jst'
// ✓ 找到时区: Asia/Tokyo
//
// 输入: 'invalid'
// ✗ 无法找到时区缩写 'INVALID'
//
// 输入: ''
// ✗ 时区缩写不能为空
?>

示例 7:与其他时区函数配合使用

<?php
// 与其他时区函数配合使用
function getDetailedTimezoneInfo($abbr, $offset_hours = null, $isDST = -1) {
    $offset_seconds = ($offset_hours !== null) ? $offset_hours * 3600 : -1;

    // 获取时区名称
    $timezone_name = timezone_name_from_abbr($abbr, $offset_seconds, $isDST);

    if ($timezone_name === false) {
        return ['error' => '未找到匹配的时区'];
    }

    try {
        // 创建 DateTimeZone 对象
        $timezone = new DateTimeZone($timezone_name);

        // 获取位置信息
        $location = timezone_location_get($timezone);

        // 获取当前偏移量
        $now = new DateTime('now', $timezone);
        $current_offset = $timezone->getOffset($now);

        // 获取时区缩写列表
        $abbreviations = timezone_abbreviations_list();
        $abbr_lower = strtolower($abbr);
        $abbr_info = isset($abbreviations[$abbr_lower]) ? $abbreviations[$abbr_lower] : [];

        return [
            'timezone_name' => $timezone_name,
            'current_offset' => $current_offset,
            'current_offset_hours' => $current_offset / 3600,
            'location' => $location !== false ? $location : '无位置信息',
            'matching_abbr_info' => $abbr_info
        ];
    } catch (Exception $e) {
        return ['error' => $e->getMessage()];
    }
}

// 获取 EST 的详细信息
echo "<h4>EST 的详细信息:</h4>";
$est_info = getDetailedTimezoneInfo('EST');
if (isset($est_info['error'])) {
    echo "错误: " . $est_info['error'];
} else {
    echo "<pre>";
    print_r($est_info);
    echo "</pre>";
}

// 输出类似:
// EST 的详细信息:
// Array
// (
//     [timezone_name] => America/New_York
//     [current_offset] => -14400
//     [current_offset_hours] => -4
//     [location] => Array
//         (
//             [country_code] => US
//             [latitude] => 40.7142
//             [longitude] => -74.0064
//             [comments] =>
//         )
//     [matching_abbr_info] => Array
//         (
//             [0] => Array
//                 (
//                     [dst] =>
//                     [offset] => -18000
//                     [timezone_id] => America/New_York
//                 )
//             ... 更多
//         )
// )
?>

常见时区缩写参考

缩写 含义 常见时区 标准时间偏移 (UTC) 夏令时偏移 (UTC)
EST Eastern Standard Time America/New_York -5 -4 (EDT)
CST Central Standard Time America/Chicago -6 -5 (CDT)
MST Mountain Standard Time America/Denver -7 -6 (MDT)
PST Pacific Standard Time America/Los_Angeles -8 -7 (PDT)
GMT Greenwich Mean Time Europe/London 0 +1 (BST)
CET Central European Time Europe/Paris +1 +2 (CEST)
EET Eastern European Time Europe/Helsinki +2 +3 (EEST)
CST China Standard Time Asia/Shanghai +8 +8 (无夏令时)
JST Japan Standard Time Asia/Tokyo +9 +9 (无夏令时)
AEST Australian Eastern Standard Time Australia/Sydney +10 +11 (AEDT)
IST Indian Standard Time Asia/Kolkata +5.5 +5.5 (无夏令时)

注意事项

  • 时区缩写具有歧义性,同一个缩写可能对应多个时区(如 "CST" 可以表示美国中部标准时间或中国标准时间)
  • 建议总是提供偏移量参数来减少歧义
  • 夏令时标志只在某些时区有效,许多时区不实行夏令时
  • 函数返回的是第一个匹配的时区名称,不一定是最合适的
  • 对于用户输入的时区缩写,应该进行验证和错误处理
  • 考虑使用 DateTimeZone 类进行更复杂的时区操作

相关函数