【问题标题】:PHP - weird timezone offsetPHP - 奇怪的时区偏移
【发布时间】:2011-05-23 15:46:17
【问题描述】:

我遇到了一个我无法理解的愚蠢问题。 下面这段代码怎么来的:

public function getFormattedOffsetFrom($refTimezoneId = 'Europe/Paris', $format = 'G\hi') {
    $timestamp = time();
    $reference = new DateTime('@'.$timestamp);
    $referenceTimeZone = new DateTimeZone($refTimezoneId);
    $reference->setTimezone($referenceTimeZone);
    $datetime = new DateTime('@'.$timestamp);
    $datetime->setTimezone($this->timezone);
    $offset = $this->timezone->getOffset($datetime) - $referenceTimeZone->getOffset($reference);
    $prefix = '+';
    if($offset < 0) {
        $prefix = '-';
        $offset = abs($offset);
    }
    return $prefix.date($format, $offset);
}

其中 $this->timezone 是位于欧洲/马德里的 DateTimeZone 的一个实例,当没有指定参数时产生 +1h00 ????

巴黎和马德里没有时间偏移。我只是不明白。

非常感谢您的帮助!!!! 弗洛伦特

【问题讨论】:

  • 啊,你是在比较巴黎马德里,抱歉,我没听懂。你能输出原始偏移量看看有什么问题吗?可能是函数内部的错误
  • 好吧,偏移量应该是0 :)
  • 我认为您必须调试该功能,看看哪里出了问题......

标签: php timezone offset


【解决方案1】:

为什么应该是 0 ?西班牙和法国都使用 GMT+1 作为时区。

http://en.wikipedia.org/wiki/File:Time_zones_of_Europe.svg

问题是您尝试使用函数date() 格式化$offset 以秒为单位,该函数期望时间戳作为第二个参数。如果 $offset == 0 date 函数将其识别为 1970-01-01 00:00:00 GMT,那么在您的时区中它将是 1970-01-01 01:00: 00 GMT+1,并且您正在使用格式返回小时和分钟,这就是您将 +1 作为输出的原因。

你必须像这样手动格式化这个时差:

$offsetH = floor( $offset / 3600 ); //full hours
$offsetM = floor(($offset - $offsetH) / 60 ); //full minutes

return sprintf("%s%sh%02s",$prefix,$offsetH,$offsetM) ;

【讨论】:

  • 他在比较巴黎马德里,我一开始也犯了同样的错误
  • 谢谢,现在说得通了;)
  • 等价于sprintf('%+03dh:%02um', $offset / 3600, $offset % 3600 / 60);
  • @Alix Axel - 不错的单线,但我不认为将分钟表示为 unsigned long 会为负偏移量提供所需的结果。 edit 刚刚检查确定 - 是的,它不打印绝对值,仍然需要在第二个变量上使用 abs()
  • @dev-null-dweller:哦,是的,PHP 中的模运算符对负数的行为很奇怪,sprintf('%+03dh:%02um', $offset / 3600, abs($offset) % 3600 / 60); 是正确的版本。
【解决方案2】:

问题可以简化为date('G', 0) 给出“1”。解决方法是使用gmdate()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多