You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP优雅实现欧洲时区名称等效判断方案咨询

优雅实现欧洲时区等效判断(PHP)

我的应用需要比较时区名称,判断它们是否等效——不同时区若有相同效果即视为匹配,目前仅处理欧洲时区。根据维基百科时区页面整理了如下分组数据:

$equalGroups = [
    // WET/GMT
    ['Europe/Lisbon', 'Europe/Dublin', 'Europe/London'],
    // CET
    ['Europe/Andorra', 'Europe/Belgrade', 'Europe/Berlin', 'Europe/Brussels',
        'Europe/Budapest', 'Europe/Gibraltar', 'Europe/Madrid', 'Europe/Malta',
        'Europe/Paris', 'Europe/Prague', 'Europe/Rome', 'Europe/Tirane',
        'Europe/Vienna', 'Europe/Warsaw', 'Europe/Zurich'],
    // EET
    ['Europe/Athens', 'Europe/Bucharest', 'Europe/Chisinau', 'Europe/Helsinki',
        'Europe/Kaliningrad', 'Europe/Kyiv', 'Europe/Riga', 'Europe/Sofia',
        'Europe/Tallinn', 'Europe/Vilnius'],
    // MSK
    ['Europe/Kirov', 'Europe/Moscow', 'Europe/Simferopol', 'Europe/Volgograd'],
];

(注:清楚其中包含争议信息,不对此展开讨论)

同一子数组内的时区名称在本场景下完全等效,示例如下:

function isEqual($a, $b)
{
    // TODO
}

isEqual('Europe/Vienna', 'Europe/Berlin')   // true (同一分组)
isEqual('Europe/Malta', 'Europe/Athens')   // false (不同分组)

我可以用循环手动实现,但想借助PHP的数组函数减少代码量,寻求更简洁优雅的实现方式。PHP的array_search仅支持精确匹配,不像JS的find能结合in_array使用,有没有简洁的实现思路?


方法一:预构建映射数组(最优性能)

先把分组转换成「时区=>分组标识」的映射,后续判断只需对比两个时区的标识是否一致,这种方式查询效率最高,适合频繁调用的场景:

// 预构建映射数组
$timezoneMap = [];
foreach ($equalGroups as $groupId => $timezones) {
    foreach ($timezones as $tz) {
        $timezoneMap[$tz] = $groupId;
    }
}

function isEqual($a, $b, $timezoneMap) {
    return isset($timezoneMap[$a], $timezoneMap[$b]) && $timezoneMap[$a] === $timezoneMap[$b];
}

// 测试
var_dump(isEqual('Europe/Vienna', 'Europe/Berlin', $timezoneMap)); // bool(true)
var_dump(isEqual('Europe/Malta', 'Europe/Athens', $timezoneMap)); // bool(false)

方法二:用数组函数直接查询(无需预构建)

如果不想预构建映射,也可以用array_filter结合in_array实现类似JS find的效果,直接查找两个时区是否属于同一分组:

function isEqual($a, $b, $equalGroups) {
    // 找到包含$a的分组
    $groupA = array_filter($equalGroups, fn($group) => in_array($a, $group));
    // 若$a不存在或$b不在$a的分组中则返回false
    return !empty($groupA) && in_array($b, reset($groupA));
}

// 测试
var_dump(isEqual('Europe/Vienna', 'Europe/Berlin', $equalGroups)); // bool(true)
var_dump(isEqual('Europe/Malta', 'Europe/Athens', $equalGroups)); // bool(false)

补充说明

  • 方法二每次调用都会遍历分组,性能不如预构建映射,适合调用次数少的场景;
  • 方法一虽然多了一步初始化,但后续查询是O(1)复杂度,更适合高频调用的业务场景。

内容的提问来源于stack exchange,提问作者ygoe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 02:23:22