将UTC偏移量转换为时区或日期

Kyl*_*oss 15 php timezone geolocation timezone-offset

对你来说很划清楚.

我从IPInfoDB的API中获取地理IP数据,它返回UTC的时区偏移,包括 DST(如果当前反映).

例如,我住在EST(-5),目前它是DST,所以geo IP API返回(-04:00)作为偏移量.

这很好,因为DST是一个令人头疼的问题.但令我惊讶的是,它引起了另一次头痛.

我在PHP中加载这些数据,通过AJAX传递给应用程序.我想在应用程序上获得IP地址的实时本地时间.

我有完美的设置,但我疯狂试图找出如何设置PHP时区以匹配偏移量,所以我可以抓住当前的小时date('H');和分钟date('i');通过AJAX传递.

我不确定是否有一个特定的功能可以根据该偏移给我当前的小时和分钟,或者是否有一种实用的方法来根据偏移设置时区(如果有效,将会应用DST) .

我一直在搜索和搜索谷歌以找到答案,但我正在做的更具体,因为已经应用了夏令时.

我在PHP.net上找到了一个似乎可以解决问题的功能(它适用于我的时区并返回正确的时间),但对于其他时区如PST,它比它应该返回1小时后即使偏移是正确的(-07:00与DST).

从函数返回的时区是Chile/EasterIsland我感觉到的原因.如果可以的话,我会让这只适用于美国,但我确实需要它在全球范围内.

这是我现在的功能.请原谅极其凌乱的代码.在过去的几个小时里,我一直在玩弄很多东西试图找出解决方案.

大部分功能都是在线发现的.

function offsetToTZ($offset) {
switch((string) $offset) {
    case '-04:30' : return 'America/Caracas'; break;
    case '-03:30' : return 'Canada/Newfoundland'; break;
    case '+03:30' : return 'Asia/Tehran'; break;
    case '+04:30' : return 'Asia/Kabul'; break;
    case '+05:30' : return 'Asia/Kolkata'; break;
    case '+05:45' : return 'Asia/Kathmandu'; break;
    case '+09:30' : return 'Australia/Darwin'; break;
}
$offset = (int) str_replace(array('0',0,':00',00,'30',30,'45',45,':','+'),'', (string) $offset);

$offset = $offset*60*60;
$abbrarray = timezone_abbreviations_list(); 
foreach ($abbrarray as $abbr) { 
    foreach($abbr as $city) { 
        if($city['offset'] == $offset) { 
            return $city['timezone_id'];
        }
    }
}
return false; 
}
Run Code Online (Sandbox Code Playgroud)

我包括用于某些时区是开关/壳体:30:45在那里.可能有一种方法可以包括它,也不需要开关/外壳.

注意:偏移量始终按原样返回+00:00-00:00从地理IP API返回.

我会感谢任何帮助或正确方向的一点.我不是PHP的新手,但偏移对我来说是一个新故事.谢谢!

uın*_*ɐɥs 46

它可以非常简单地完成,将偏移量转换为秒并将其传递给timezone_name_from_abbr:

<?php
$offset = '-7:00';

// Calculate seconds from offset
list($hours, $minutes) = explode(':', $offset);
$seconds = $hours * 60 * 60 + $minutes * 60;
// Get timezone name from seconds
$tz = timezone_name_from_abbr('', $seconds, 1);
// Workaround for bug #44780
if($tz === false) $tz = timezone_name_from_abbr('', $seconds, 0);
// Set timezone
date_default_timezone_set($tz);

echo $tz . ': ' . date('r');
Run Code Online (Sandbox Code Playgroud)

演示

第三个参数timezone_name_from_abbr控制是否调整夏令时.

错误#44780:

timezone_name_from_abbr()将在某些时区偏移上返回false.特别是 - 夏威夷,其GMT偏移为-10,-36000秒.

参考文献:

  • @BigRoss我已经更新了代码来解决一个bug. (2认同)