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
相关产品推荐
相关产品推荐

