代码之家  ›  专栏  ›  技术社区  ›  pjbeardsley

使用datetime/datetime zone在PHP中调整时区

  •  5
  • pjbeardsley  · 技术社区  · 15 年前

    有很多关于在PHP中进行时区调整的信息,但是由于所有的噪声,我还没有找到一个具体的答案。

    给定一个时区中的时间,我想将其转换为另一个时区中的时间。

    This 基本上是我想要做的,但是我需要能够只使用内置的php libs,而不是pear-date。

    这是我一直在做的,但它似乎总是给我相对于格林尼治标准时间的补偿:

    $los_angeles_time_zone = new DateTimeZone('America/Los_Angeles');
    $hawaii_time_zone = new DateTimeZone('Pacific/Honolulu');
    
    $date_time_los_angeles = new DateTime('2009-09-18 05:00:00', $los_angeles_time_zone);
    printf("LA Time: %s<br/>", $date_time_los_angeles->format(DATE_ATOM));
    
    $time_offset = $hawaii_time_zone->getOffset($date_time_los_angeles);
    printf("Offset: %s<br/>", $time_offset);
    

    这是输出:

    洛杉矶时间:2009-09-18t05:00:00-07:00
    偏移量:- 36000

    我期待3小时(10800秒)。但是,7点告诉我,它将所有的东西都与格林尼治标准时间保持相对,这可能解释了为什么它会给我“绝对”的偏移量。

    如果没有格林威治标准时间的所有内容,我怎么才能得到两个时区之间的时差呢?

    谢谢。

    更新:

    我突然想到我可以做到这一点,得到我想要的:

        $date_time_los_angeles = new DateTime('2009-09-18 05:00:00', $los_angeles_time_zone);
    printf("LA Time: %s<br/>", $date_time_los_angeles->format(DATE_ATOM));
    
    $date_time_hawaii = new DateTime('2009-09-18 05:00:00', $hawaii_time_zone);
    printf("Hawaii Time: %s<br/>", $date_time_hawaii->format(DATE_ATOM));
    
    
    $time_offset = $los_angeles_time_zone->getOffset($date_time_los_angeles) - $hawaii_time_zone->getOffset($date_time_los_angeles);
    printf("Offset: %s<br/>", $time_offset);
    

    但我觉得很尴尬。有人知道更干净的方法吗?

    3 回复  |  直到 14 年前
        1
  •  8
  •   GZipp    15 年前

    下面是一些使用datetime类的函数。第一个将返回两个时区之间的秒数差。第二个返回时间从一个时区到另一个时区的“转换”。

    function timezone_diff($tz_from, $tz_to, $time_str = 'now')
    {
        $dt = new DateTime($time_str, new DateTimeZone($tz_from));
        $offset_from = $dt->getOffset();
        $timestamp = $dt->getTimestamp();
        $offset_to = $dt->setTimezone(new DateTimezone($tz_to))->setTimestamp($timestamp)->getOffset();
        return $offset_to - $offset_from;
    }
    
    function time_translate($tz_from, $tz_to, $time_str = 'now', $format = 'Y-m-d H:i:s')
    {
        $dt = new DateTime($time_str, new DateTimezone($tz_from));
        $timestamp = $dt->getTimestamp();
        return $dt->setTimezone(new DateTimezone($tz_to))->setTimestamp($timestamp)->format($format);
    }
    

    演示:

    $los_angeles_time = '2009-09-18 05:00:00';
    $los_angeles_tz   = 'America/Los_Angeles';
    $hawaii_tz        = 'Pacific/Honolulu';
    
    $los_angeles_hawaii_diff = timezone_diff($los_angeles_tz, $hawaii_tz, $los_angeles_time);
    echo $los_angeles_hawaii_diff . '<br />';
    
    $hawaii_time = time_translate($los_angeles_tz, $hawaii_tz, $los_angeles_time);
    echo $hawaii_time . '<br />';
    
        2
  •  1
  •   Jim Rubenstein    14 年前

    正如gzip所评论的,他的代码实际上只适用于php>=5.3.0。这很好,但是-这里有一个可以在php>=5.2.0中使用的版本。(顺便说一句,它还可以在5.3+中工作,并且可以少调用2个函数)

    <?php
    function time_translate($tz_from, $tz_to, $time_str = 'now', $format = 'Y-m-d H:i:s')
    {
        $dt = new DateTime($time_str, new DateTimezone($tz_from));
        $dt->setTimezone(new DateTimezone($tz_to));
        return $dt->format($format);
    }
    
    $time_diffs = array('now', '-1 hour', '-1 day', '-1 week', '-1 month', '+1 hour', '+1 week', '+1 month');
    
    foreach ($time_diffs as $diff)
    {
     echo "{$diff}:"
      . "\n\t"
      . "Current: " . date("Y-m-d H:i:s", strtotime($diff))
      . "\n\t"
      . "UTC: " . time_translate("US/Eastern", "UTC", $diff)
      . "\n\n";
    }
    
        3
  •  0
  •   mauris    15 年前

    简单地从第二次减去第一次。

    你可以得到以秒为单位的时间差。