[英]Convert UTC offset to timezone or date
为您准备的头抓板。
我正在从IPInfoDB的API中获取地理IP数据,它从UTC返回包括 DST的时区偏移(如果当前已反映)。
例如,我住在EST(-5),目前是DST,因此geo IP API返回( -04:00
)作为偏移量。
因为DST令人头疼,所以这太好了。 但是令我惊讶的是,它又引起了头疼。
我将此数据加载到PHP中,以通过AJAX传递给应用程序。 我想在应用程序上获取IP地址的实时本地时间。
我已经把所有的设置都完美了,但是我很疯狂地试图找出如何设置PHP时区来匹配偏移量,这样我就可以获取当前的小时date('H');
和分钟date('i');
通过AJAX传递给。
我不确定是否有特定功能可以根据该偏移量给我当前的小时和分钟,或者是否有一种实用的方法可以基于偏移量设置时区(如果已经生效,则已经应用了DST) 。
我一直在搜索Google,以找到答案,但是由于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;
}
我包括了某些时区的开关/盒,它们是:30
和:45
。 可能有一种方法也可以包括在内,而无需开关/外壳。
注意:偏移量总是从geo IP API中按+00:00
或-00:00
返回。
我将不胜感激,也为您提供了正确的指导。 我不是PHP的新手,但抵消对我来说是个新故事。 谢谢!
通过将偏移量转换为秒并将其传递到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');
timezone_name_from_abbr
的第三个参数控制是否调整夏令时。
错误#44780 :
timezone_name_from_abbr()在某些时区偏移量上将返回false。 特别是-夏威夷,与格林尼治标准时间偏移为-10,-36000秒。
参考文献:
date_default_timezone_set('UTC');
$timezones = array();
foreach (DateTimeZone::listAbbreviations() as $key => $array)
{
$timezones = array_merge($timezones, $array);
}
$utc = new DateTimeZone('UTC');
$timezone_offset = '+02:00'; # 2H
$sign = substr($timezone_offset, 0, 1) == '+'? '': '-';
$offset = substr($timezone_offset, 1, 2) . 'H' . substr($timezone_offset, 4, 2) . 'M';
$operation = $sign == ''? 'add': 'sub';
$start = new DateTime('', $utc);
$date = new DateTime('', $utc);
$date->{$operation}(new DateInterval("PT{$offset}"));
$offset = $start->diff($date)->format('%r') . ($start->diff($date)->h * 3600 + $start->diff($date)->m * 60 + $start->diff($date)->s); # 7200 (2H)
echo $offset, PHP_EOL;
echo $date->format('Y-m-d H:i:s'), PHP_EOL;
foreach($timezones as $timezone)
{
if($timezone['offset'] == $offset)
{
echo $timezone['timezone_id'], PHP_EOL;
}
}
我可能在某些方面误解了您,但希望对您有所帮助,如果您更具体,我可能会有所帮助。
对于智利,我得到:
-25200 (-7h)
2012-08-07 18:05:24 (current time 2012-08-08 01:05:24)
Chile/EasterIsland
上面示例的输出:
7200
2012-08-08 02:49:56
Europe/London
Europe/Belfast
Europe/Gibraltar
Europe/Guernsey
Europe/Isle_of_Man
Europe/Jersey
GB
Africa/Khartoum
Africa/Blantyre
Africa/Bujumbura
Africa/Gaborone
Africa/Harare
Africa/Kigali
Africa/Lubumbashi
Africa/Lusaka
Africa/Maputo
Africa/Windhoek
Europe/Berlin
Africa/Algiers
Africa/Ceuta
Africa/Tripoli
Africa/Tunis
Arctic/Longyearbyen
Atlantic/Jan_Mayen
CET
Europe/Amsterdam
Europe/Andorra
Europe/Athens
Europe/Belgrade
Europe/Bratislava
Europe/Brussels
Europe/Budapest
Europe/Chisinau
Europe/Copenhagen
Europe/Gibraltar
Europe/Kaliningrad
Europe/Kiev
Europe/Lisbon
Europe/Ljubljana
Europe/Luxembourg
Europe/Madrid
Europe/Malta
Europe/Minsk
Europe/Monaco
Europe/Oslo
Europe/Paris
Europe/Podgorica
Europe/Prague
Europe/Riga
Europe/Rome
Europe/San_Marino
Europe/Sarajevo
Europe/Simferopol
Europe/Skopje
Europe/Sofia
Europe/Stockholm
Europe/Tallinn
Europe/Tirane
Europe/Tiraspol
Europe/Uzhgorod
Europe/Vaduz
Europe/Vatican
Europe/Vienna
Europe/Vilnius
Europe/Warsaw
Europe/Zagreb
Europe/Zaporozhye
Europe/Zurich
WET
Europe/Kaliningrad
Europe/Helsinki
Africa/Cairo
Africa/Tripoli
Asia/Amman
Asia/Beirut
Asia/Damascus
Asia/Gaza
Asia/Istanbul
Asia/Nicosia
EET
Europe/Athens
Europe/Bucharest
Europe/Chisinau
Europe/Istanbul
Europe/Kaliningrad
Europe/Kiev
Europe/Mariehamn
Europe/Minsk
Europe/Moscow
Europe/Nicosia
Europe/Riga
Europe/Simferopol
Europe/Sofia
Europe/Tallinn
Europe/Tiraspol
Europe/Uzhgorod
Europe/Vilnius
Europe/Warsaw
Europe/Zaporozhye
Asia/Jerusalem
Asia/Gaza
Asia/Tel_Aviv
MET
Africa/Johannesburg
Africa/Maseru
Africa/Mbabane
Africa/Windhoek
Africa/Windhoek
Africa/Ndjamena
Europe/Lisbon
Europe/Madrid
Europe/Monaco
Europe/Paris
WET
Europe/Luxembourg
钉我的时区。
$UTC_offset = '+03:00';
$date = new \DateTime('now', 'UTC');
var_dump($date);
$timezone = new \DateTimeZone(str_replace(':', '', $UTC_offset));
$date->setTimezone($timezone);
var_dump($date);
结果:
class DateTime#205 (3) {
public $date =>
string(26) "2015-01-20 06:00:00.000000"
public $timezone_type =>
int(3)
public $timezone =>
string(3) "UTC"
}
class DateTime#205 (3) {
public $date =>
string(26) "2015-01-20 09:00:00.000000"
public $timezone_type =>
int(1)
public $timezone =>
string(6) "+03:00"
}
您可能想看一下DateTime
PHP扩展(除非已在编译时将其特别禁用,否则默认情况下,它已启用并包含在所有所有版本大于等于5.2.0的PHP中)。
它可以很好地完成您需要的一切。
不建议将时区偏移量映射回时区标识符。 许多时区共享相同的偏移量。
即使在一个国家内,这也是有问题的。 考虑在美国,中央标准时间( America/Chicago
)和America/New_York
东部夏令时间( America/New_York
)在一年中的不同时间使用-5偏移量。
还请考虑到,这些时区中的某些时区有时同时使用-5。 例如,UTC-5中2013年11月3日星期日凌晨1:00可能在CDT或EST中。 您无法仅通过-5来区分它是哪个时区。
如今, DateTimeZone
构造函数可以显式接受UTC偏移量,据我所知。
所以就:
$timeZone = new DateTimeZone('+0100');
说明文件:
http://php.net/manual/en/datetimezone.construct.php
注意:根据该文档链接,此新的构造函数用法自PHP 5.5.10版本起可用。
您还可以使用格林尼治标准时间,然后将其转换为您的要求
<?php
echo gmdate("M d Y H:i:s", mktime(0, 0, 0, 1, 1, 1998));
?>
GMT是格林威治标准时间,在世界各地都很普遍。
这项工作对我来说:
function Get_Offset_Date($Offset, $Unixtime = false, $Date_Format = 'Y.m.d,H:i')
{
try
{
$date = new DateTime("now",new DateTimeZone($Offset));
if($Unixtime)
{
$date->setTimestamp($Unixtime);
}
$Unixtime = $date->getTimestamp();
return $date->format($Date_Format);
}
catch(Exception $e)
{
return false;
}
}
要使用它,只需调用以下命令即可获取当前时间:
echo Get_Offset_Date('+2:00');
这是获取偏移日期(输入为unixtime)
echo Get_Offset_Date('+2:00',1524783867);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.