将UTC偏移量转换为时区或日期 [英] Convert UTC offset to timezone or date

查看:129
本文介绍了将UTC偏移量转换为时区或日期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对你而言,头部划伤者。



我从 IPInfoDB 的API获取地理位置IP数据,它会从UTC 返回包含 DST(如果当前已反映)的时区偏移量。

例如,我住在EST(-5)它是DST,因此geo IP API返回( -04:00 )作为抵消。



这太棒了因为夏令时是一个令人头痛的头痛。但令我惊讶的是,它引起了另一场头痛。

我用PHP加载这些数据,并通过AJAX传递给应用程序。我希望在应用程序中拥有IP地址的本地实时时间。



我已经完全设置了这些设置,但我正在疯狂地试图弄清楚如何设置PHP时区以匹配偏移量,这样我就可以抓住当前小时 date('H'); 和分钟 date('i') ; 通过AJAX传递。



我不确定是否有一个特定的函数可以给我当前的小时数和分钟数或者是否有切实可行的方法来设置基于偏移量的时区(如果有效,将应用DST)。



我一直在搜索并搜索谷歌找到答案,但我所做的更具体,因为已经应用了DST。



我在 PHP.net 似乎有诀窍(它适用于我的时区并返回正确的时间),但对于其他时区(例如PST),它返回1小时LAT呃比它应该是即使偏移是正确的( -07:00 与DST)。



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



这是我现在的功能。请原谅非常混乱的代码。在过去的几个小时里,我一直在玩弄大量的东西,试图找出解决方案。



大部分功能都在网上找到。

 函数offsetToTZ($ offset){
switch((string)$ offset){
case'-04:30':返回'美国/加拉加斯';打破;
案例'-03:30':返回'加拿大/纽芬兰';打破;
case'+03:30':return'Asia / Tehran';打破;
case'+04:30':return'Asia / Kabul';打破;
案例'+05:30':返回'亚洲/加尔各答';打破;
case'+05:45':return'Asia / Kathmandu';打破;
case'+09:30':return'Australia / Darwin';打破;

$ 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 $城市[ 'timezone_id'];
}
}
}
返回false;
}

我包含了某些时区的开关/外壳:30 :45 在那里。可能还有一种方法可以包括那些也不需要开关/情况。



注意:偏移总是返回为 +00:00 -00:00 来自地理IP API。



我会很感激任何帮助或正确的方向。我并不是PHP新手,但补偿对我来说是一个新故事。谢谢!

解决方案

通过将偏移量转换为秒并将其传递给 timezone_name_from_abbr

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

//计算偏移量
list($ hours,$ minutes)= explode(':',$ offset)的秒数;
$秒= $小时* 60 * 60 + $分钟* 60;
//从秒获取时区名称
$ tz = timezone_name_from_abbr('',$ seconds,1);
//针对错误#44780的解决方法
if($ tz === false)$ tz = timezone_name_from_abbr('',$ seconds,0);
//设定时区
date_default_timezone_set($ tz);

echo $ tz。 ':'。日期( R);

演示



第三个参数 timezone_name_from_abbr 控制是否调整夏令时。 / p>

错误#44780


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


参考文献:




A head scratcher for you.

I am grabbing geo IP data from IPInfoDB's API and it returns a timezone offset from UTC including DST (if currently reflected).

For example, I live in EST (-5) and currently it's DST, so the geo IP API returns (-04:00) as the offset.

This is wonderful since DST is a freaking headache. But to my surprise, it caused another headache.

I load this data in PHP to be passed via AJAX to the application. I would like to have the live local time of the IP address on the app.

I have that all set perfectly, but I am going crazy trying to figure out how to set the PHP timezone to match the offset so I can just grab the current hours date('H'); and minutes date('i'); to pass to via AJAX.

I am unsure if there is a specific function that can just give me the current hours and minutes based on that offset or if there is a practical way to set the timezone based on the offset (which will have DST already applied if is in effect).

I've been searching and searching Google to find an answer to this, but what I am doing is more specific since DST is already applied.

I found one function on PHP.net that seems to do the trick (it works for my timezone and returns the correct time) although for other timezones such as PST, it's returning 1 hour later than it should be even though the offset is correct (-07:00 with DST).

The timezone returned from the function is Chile/EasterIsland which I have a feeling is the cause. If I could, I would make this only work for the USA, but I do need it to be worldwide.

This is the function I have now. Please excuse the extremely messy code. I have been playing around with tons of things over the last few hours trying to figure out a solution.

Most of the functionality was found online.

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; 
}

I included the switch/case for certain timezones that are :30 and :45 out there. There may be a way to include that also without the need of the switch/case.

NOTE: The offsets are always returned as such +00:00 or -00:00 from the geo IP API.

I would appreciate any help or a point in the right direction. I'm not very novice with PHP, but offsets are a new story for me. Thanks!

解决方案

It can be done quite simply, by turning the offset into seconds and passing it to 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');

Demo

The third parameter of timezone_name_from_abbr controls whether to adjust for daylight saving time or not.

Bug #44780:

timezone_name_from_abbr() will return false on some time zone offsets. In particular - Hawaii, which has a -10 from GMT offset, -36000 seconds.

References:

这篇关于将UTC偏移量转换为时区或日期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆