首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >时区和播出日期

时区和播出日期
EN

Stack Overflow用户
提问于 2015-06-01 18:19:04
回答 2查看 264关注 0票数 2

我正在努力改变电视连续剧的播出日期。我使用的API将返回以下确切值:

代码语言:javascript
复制
Datetime: 2015-05-31 21:00
Country: US
Timezone: GMT-5 +DST

现在,我试图用给定的数据检索时区(欧洲/罗马)的播出日期时间。我要做的是:

代码语言:javascript
复制
$date = new DateTime('2015-05-31 21:00', new DateTimeZone('GMT-5 +DST'));
$date->setTimezone(new DateTimeZone('Europe/Rome'));
echo $date->format('Y-m-d H:i:s');

其中的指纹:

代码语言:javascript
复制
2015-06-01 04:00:00

我对是否是正确的方法有些怀疑,因为其他提供同样信息的网站说,上述事件在我的国家(IT/意大利)于6月1日03:00 (而不是04:00)播出。

所以我做得对吗,我比较结果的网站错了吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-01 18:54:25

如果使用new DateTimeZone('GMT-5'),则得到相同的值。GMT-5 +DST不是一个时区名称的有效值,类DateTimeZone的构造函数使用的可能和它从提供给它的参数中成功解析的一样多。

我认为您应该“手动”解析Timezone:的值,如果字符串以+DST结尾,则调整偏移量1小时。

如果您知道返回的时区总是GMT-5,那么只需检查字符串是否为GMT-5 +DST,然后使用GMT-4

否则,您可以尝试使用正则表达式解析接收到的时区:

代码语言:javascript
复制
// The timezone received from the API
$timezone = 'GMT-5 +DST';

$m = array();
if (preg_match('/^GMT([+-]\d+)( \+DST)?$/', $timezone, $m)) {
    if ($m[2] == ' +DST') {
        // Compute the correct offset using DST
        $tz = sprintf('Etc/GMT%+d', -(intval($m[1])+1));
    } else {
        // No DST; use the correct name of the time zone
        $tz = sprintf('Etc/GMT%+d', -intval($m[1]));
    }
} else {
    // The timezone name has a different format; use it as is
    // You should do better checks here
    $tz = $timestamp;
} 
$date = new DateTime('2015-05-31 21:00', new DateTimeZone($tz));
$date->setTimezone(new DateTimeZone('Europe/Rome'));
echo $date->format('Y-m-d H:i:s');

更新:@matt注意到,GMT时区的正确名称是Etc/GMT,后面跟着偏移量。

PHP 5.5PHP 5.6接受并正确解释没有Etc/前缀的GMT时区。旧版本(5.35.4)抛出带有消息'DateTimeZone::__construct(): Unknown or bad timezone (GMT-4)'的异常

我更新了上面的代码以使用正确的名称。在这一行中,你必须注意到一些事情:

代码语言:javascript
复制
$tz = sprintf('Etc/GMT%+d', -(intval($m[1])+1));

  • +格式字符串上的sprintf()符号强制在数字前面生成+符号(如果数字为正数);对于负数,则生成带有或不带负号的-符号;
  • +1intval($m[1])+1中做DST校正;
  • 计算值的符号被更改(注意前面的- ),因为PHP使用的时区数据库有一种奇怪的行为;这种行为在文档中解释: 警告: 请不要使用这里列出的任何时区(UTC之外),它们只存在于向后兼容的原因。 警告 如果您无视上述警告,还请注意,提供PHP时区支持的IANA时区数据库使用POSIX样式标志,这将导致Etc/GMT+n和Etc/GMT时区与常用时区相反。

这意味着GMT-5由上面的代码转换为Etc/GMT+5GMT-5 +DST被转换为Etc/GMT+4

票数 2
EN

Stack Overflow用户

发布于 2015-06-01 19:29:15

这应该能行。它解析您提供的值,将输入时区手动调整为UTC。然后使用PHP的时区(即IANA时区)将其转换为所需的目标时区。

代码语言:javascript
复制
// The values received from the API
$datetime = '2015-05-31 21:00';
$timezone = 'GMT-5 +DST';

// Parse the time zone
$m = array();
preg_match('/GMT([+-]\d+)( \+DST)?/', $timezone, $m);
$offset = intval($m[1]);
$dst = sizeof($m) == 3;

// Adjust for the DST flag
if ($dst) $offset++;

// Apply the offset to the datetime given
$dt = new DateTime($datetime, new DateTimeZone("UTC"));
$dt->setTimestamp($dt->getTimestamp() - ($offset * 3600));

// Convert it to whatever time zone you like
$dt->setTimezone(new DateTimeZone('Europe/Rome'));
echo $dt->format('Y-m-d H:i:s');
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30580466

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档