PHP timezone_location_get()函数

timezone_location_get() 函数返回指定时区的位置信息,包括国家代码、经纬度和注释。这个函数需要传入一个 DateTimeZone 对象作为参数。

注意:并非所有时区都有位置信息,只有基于地理位置的时区(如 "America/New_York"、"Asia/Shanghai")才有位置信息,而抽象时区(如 "UTC"、"GMT")没有位置信息。

语法

timezone_location_get(DateTimeZone $object) : array|false

参数说明

参数 描述
object

必需。 一个 DateTimeZone 对象。

返回值

成功时返回一个关联数组,包含时区的位置信息。如果时区没有位置信息,返回 false

返回数组的结构

键名 描述 示例
country_code 国家代码(ISO 3166-1 两位字母代码) US, CN, GB, JP
latitude 纬度(浮点数) 40.7142, 31.0456
longitude 经度(浮点数) -74.0064, 121.3997
comments 注释(可选,可能为空字符串) "", "New York"

示例

示例 1:基本用法

<?php
// 创建 DateTimeZone 对象
$timezone = new DateTimeZone('America/New_York');

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

if ($location !== false) {
    echo "<pre>";
    print_r($location);
    echo "</pre>";

    echo "<h4>解析的位置信息:</h4>";
    echo "国家代码: " . $location['country_code'] . "<br>";
    echo "纬度: " . $location['latitude'] . "<br>";
    echo "经度: " . $location['longitude'] . "<br>";
    echo "注释: " . ($location['comments'] ?: '(无)') . "<br>";
} else {
    echo "该时区没有位置信息";
}

// 输出类似:
// Array
// (
//     [country_code] => US
//     [latitude] => 40.7142
//     [longitude] => -74.0064
//     [comments] =>
// )
// 解析的位置信息:
// 国家代码: US
// 纬度: 40.7142
// 经度: -74.0064
// 注释: (无)
?>

示例 2:多个时区的位置信息

<?php
// 获取多个时区的位置信息
$timezones = [
    'America/New_York',
    'Asia/Shanghai',
    'Europe/London',
    'Australia/Sydney',
    'Africa/Cairo',
    'UTC'  // 抽象时区,没有位置信息
];

foreach ($timezones as $tz) {
    $timezone = new DateTimeZone($tz);
    $location = timezone_location_get($timezone);

    echo "<h4>" . $tz . "</h4>";
    if ($location !== false) {
        echo "国家代码: " . $location['country_code'] . "<br>";
        echo "纬度: " . $location['latitude'] . "<br>";
        echo "经度: " . $location['longitude'] . "<br>";
        echo "注释: " . ($location['comments'] ?: '(无)') . "<br>";
    } else {
        echo "该时区没有位置信息<br>";
    }
    echo "<hr>";
}

// 输出类似:
// America/New_York
// 国家代码: US
// 纬度: 40.7142
// 经度: -74.0064
// 注释: (无)
//
// Asia/Shanghai
// 国家代码: CN
// 纬度: 31.0456
// 经度: 121.3997
// 注释: (无)
//
// Europe/London
// 国家代码: GB
// 纬度: 51.508
// 经度: -0.1257
// 注释:
//
// Australia/Sydney
// 国家代码: AU
// 纬度: -33.86
// 经度: 151.21
// 注释:
//
// Africa/Cairo
// 国家代码: EG
// 纬度: 30.05
// 经度: 31.25
// 注释:
//
// UTC
// 该时区没有位置信息
?>

示例 3:错误处理

<?php
// 处理可能出现的错误
function getTimezoneLocation($timezone_name) {
    try {
        $timezone = new DateTimeZone($timezone_name);
        $location = timezone_location_get($timezone);

        if ($location === false) {
            return "时区 '{$timezone_name}' 没有位置信息";
        }

        return $location;
    } catch (Exception $e) {
        return "错误: " . $e->getMessage();
    }
}

// 测试各种情况
$test_timezones = [
    'America/New_York',  // 有效时区,有位置信息
    'UTC',               // 有效时区,但无位置信息
    'Invalid/Timezone',  // 无效时区
    'Asia/Tokyo',        // 有效时区,有位置信息
    'GMT'                // 抽象时区,无位置信息
];

foreach ($test_timezones as $tz) {
    $result = getTimezoneLocation($tz);
    echo "<h4>" . $tz . "</h4>";
    if (is_array($result)) {
        echo "<pre>";
        print_r($result);
        echo "</pre>";
    } else {
        echo $result;
    }
    echo "<br><br>";
}

// 输出类似:
// America/New_York
// Array
// (
//     [country_code] => US
//     [latitude] => 40.7142
//     [longitude] => -74.0064
//     [comments] =>
// )
//
// UTC
// 时区 'UTC' 没有位置信息
//
// Invalid/Timezone
// 错误: DateTimeZone::__construct(): Unknown or bad timezone (Invalid/Timezone)
//
// Asia/Tokyo
// Array
// (
//     [country_code] => JP
//     [latitude] => 35.6544
//     [longitude] => 139.7447
//     [comments] =>
// )
//
// GMT
// 时区 'GMT' 没有位置信息
?>

示例 4:在地图上显示时区位置

<?php
// 生成简单的地图位置信息
function getTimezoneMapLink($timezone_name) {
    try {
        $timezone = new DateTimeZone($timezone_name);
        $location = timezone_location_get($timezone);

        if ($location === false) {
            return "无法获取时区位置信息";
        }

        $lat = $location['latitude'];
        $lng = $location['longitude'];
        $country = $location['country_code'];

        // 生成Google Maps链接
        $google_maps = "https://www.google.com/maps?q={$lat},{$lng}";

        // 生成OpenStreetMap链接
        $osm = "https://www.openstreetmap.org/?mlat={$lat}&mlon={$lng}#map=10/{$lat}/{$lng}";

        return [
            'timezone' => $timezone_name,
            'country' => $country,
            'latitude' => $lat,
            'longitude' => $lng,
            'google_maps' => $google_maps,
            'openstreetmap' => $osm
        ];
    } catch (Exception $e) {
        return "错误: " . $e->getMessage();
    }
}

// 测试
$timezones = ['America/New_York', 'Asia/Shanghai', 'Europe/London', 'Australia/Sydney'];

foreach ($timezones as $tz) {
    $result = getTimezoneMapLink($tz);
    if (is_array($result)) {
        echo "<h4>" . $result['timezone'] . "</h4>";
        echo "国家: " . $result['country'] . "<br>";
        echo "坐标: " . $result['latitude'] . ", " . $result['longitude'] . "<br>";
        echo "Google Maps: <a href='" . $result['google_maps'] . "' target='_blank'>查看地图</a><br>";
        echo "OpenStreetMap: <a href='" . $result['openstreetmap'] . "' target='_blank'>查看地图</a><br>";
    } else {
        echo "<h4>" . $tz . "</h4>";
        echo $result;
    }
    echo "<hr>";
}

// 输出类似:
// America/New_York
// 国家: US
// 坐标: 40.7142, -74.0064
// Google Maps: 查看地图
// OpenStreetMap: 查看地图
//
// Asia/Shanghai
// 国家: CN
// 坐标: 31.0456, 121.3997
// Google Maps: 查看地图
// OpenStreetMap: 查看地图
//
// Europe/London
// 国家: GB
// 坐标: 51.508, -0.1257
// Google Maps: 查看地图
// OpenStreetMap: 查看地图
//
// Australia/Sydney
// 国家: AU
// 坐标: -33.86, 151.21
// Google Maps: 查看地图
// OpenStreetMap: 查看地图
?>

示例 5:查找特定国家的时区

<?php
// 查找特定国家的时区并获取位置信息
function getTimezonesByCountryWithLocation($country_code) {
    $timezones = timezone_identifiers_list(DateTimeZone::PER_COUNTRY, $country_code);
    $result = [];

    foreach ($timezones as $timezone) {
        $tz = new DateTimeZone($timezone);
        $location = timezone_location_get($tz);

        if ($location !== false) {
            $result[] = [
                'timezone' => $timezone,
                'location' => $location
            ];
        }
    }

    return $result;
}

// 获取美国的时区位置信息
$us_timezones = getTimezonesByCountryWithLocation('US');

echo "<h4>美国时区位置信息(前5个):</h4>";
echo "<pre>";
$count = 0;
foreach ($us_timezones as $info) {
    if ($count++ >= 5) break;
    echo $info['timezone'] . ":\n";
    echo "  国家代码: " . $info['location']['country_code'] . "\n";
    echo "  纬度: " . $info['location']['latitude'] . "\n";
    echo "  经度: " . $info['location']['longitude'] . "\n";
    echo "  注释: " . ($info['location']['comments'] ?: '(无)') . "\n\n";
}
echo "</pre>";
echo "美国总时区数: " . count($us_timezones);

// 输出类似:
// 美国时区位置信息(前5个):
// America/New_York:
//   国家代码: US
//   纬度: 40.7142
//   经度: -74.0064
//   注释: (无)
//
// America/Chicago:
//   国家代码: US
//   纬度: 41.85
//   经度: -87.65
//   注释: (无)
//
// America/Denver:
//   国家代码: US
//   纬度: 39.7392
//   经度: -104.9847
//   注释: (无)
//
// America/Los_Angeles:
//   国家代码: US
//   纬度: 34.0522
//   经度: -118.2428
//   注释: (无)
//
// America/Juneau:
//   国家代码: US
//   纬度: 58.3019
//   经度: -134.4197
//   注释: (无)
//
// 美国总时区数: 29
?>

示例 6:比较不同时区的位置

<?php
// 比较不同时区的位置
function compareTimezoneLocations($timezone1, $timezone2) {
    try {
        $tz1 = new DateTimeZone($timezone1);
        $tz2 = new DateTimeZone($timezone2);

        $loc1 = timezone_location_get($tz1);
        $loc2 = timezone_location_get($tz2);

        if ($loc1 === false || $loc2 === false) {
            return "无法比较:至少一个时区没有位置信息";
        }

        // 计算距离(简单的大圆距离公式,近似值)
        $lat1 = deg2rad($loc1['latitude']);
        $lon1 = deg2rad($loc1['longitude']);
        $lat2 = deg2rad($loc2['latitude']);
        $lon2 = deg2rad($loc2['longitude']);

        $delta_lat = $lat2 - $lat1;
        $delta_lon = $lon2 - $lon1;

        $a = sin($delta_lat/2) * sin($delta_lat/2) +
             cos($lat1) * cos($lat2) *
             sin($delta_lon/2) * sin($delta_lon/2);
        $c = 2 * atan2(sqrt($a), sqrt(1-$a));
        $distance = 6371 * $c; // 地球半径6371km

        return [
            'timezone1' => $timezone1,
            'timezone2' => $timezone2,
            'location1' => $loc1,
            'location2' => $loc2,
            'distance_km' => round($distance, 2)
        ];
    } catch (Exception $e) {
        return "错误: " . $e->getMessage();
    }
}

// 比较几个时区
$comparisons = [
    ['America/New_York', 'America/Los_Angeles'],
    ['Asia/Shanghai', 'Asia/Tokyo'],
    ['Europe/London', 'Australia/Sydney']
];

foreach ($comparisons as $pair) {
    $result = compareTimezoneLocations($pair[0], $pair[1]);
    if (is_array($result)) {
        echo "<h4>比较: " . $result['timezone1'] . " 和 " . $result['timezone2'] . "</h4>";
        echo "距离: " . $result['distance_km'] . " 公里<br><br>";
    } else {
        echo "<h4>比较: " . $pair[0] . " 和 " . $pair[1] . "</h4>";
        echo $result . "<br><br>";
    }
}

// 输出类似:
// 比较: America/New_York 和 America/Los_Angeles
// 距离: 3935.76 公里
//
// 比较: Asia/Shanghai 和 Asia/Tokyo
// 距离: 1763.58 公里
//
// 比较: Europe/London 和 Australia/Sydney
// 距离: 16990.42 公里
?>

注意事项

  • timezone_location_get() 只适用于基于地理位置的时区,不适用于抽象时区(如 "UTC"、"GMT"、"Etc/GMT+8" 等)
  • 时区的位置信息通常表示该时区的"代表城市"的位置,而不是整个时区的地理范围
  • 位置信息基于系统的时区数据库,不同系统可能有细微差异
  • 某些时区可能没有位置信息,函数会返回 false
  • 纬度范围是 -90 到 90,经度范围是 -180 到 180
  • 在使用前应检查返回值是否为 false

哪些时区有位置信息?

时区类型 示例 是否有位置信息 说明
地理时区 America/New_York, Asia/Shanghai, Europe/London 基于具体地理位置,有国家代码和经纬度
抽象时区 UTC, GMT, Etc/GMT+8 抽象的时间标准,无具体地理位置
链接时区 US/Eastern, Australia/Canberra 通常有 指向其他时区的链接,位置信息与目标时区相同
废弃时区 US/Alaska, Canada/Eastern 可能有 已废弃但仍支持的时区,可能仍有位置信息

相关函数