使用DateTime在PHP中进行时区转换

时间:2013-06-12 13:08:29

标签: php datetime timezone

我最近找到了一些解决方案并决定使用这个解决方案,所以我在其中一个课程中创​​建了以下方法:

public static function date($format, $time = false, $from_timezone = false, $to_timezone = false) {

    if (!$time) {
        $time = time();
    }

    if (($from_timezone === $to_timezone) || (!$from_timezone || !$to_timezone)) {
        return date($format, $time);
    }

    $from_tz = new DateTimeZone($from_timezone);
    $to_tz = new DateTimeZone($to_timezone);

    $dt = new DateTime();
    $dt->setTimezone($from_tz);
    $dt->setTimestamp($time);

    $offset = $to_tz->getOffset($dt);

    return date($format, $dt->format('U') + $offset);
}

然后我做了一个简单的测试 - 我将日期时间转换为其他时区,然后将结果转换回原始时区,期望获得原始日期时间。

    $format = 'Y-m-d H:i:s';
    $initialtime = '2013-06-13 12:00:00';

    echo $initialtime;
    echo '<br/>';

    $convtime = TimezoneLib::date($format, strtotime($initialtime), 'Canada/Atlantic', 'Europe/Prague');
    echo $convtime;
    echo '<br/>';

    echo TimezoneLib::date($format, strtotime($convtime), 'Europe/Prague', 'Canada/Atlantic');
    die();

这是输出

2013-06-13 12:00:00 // Original
2013-06-13 14:00:00 // Converted
2013-06-13 11:00:00 // Converted to original timezone

为什么他们不匹配?我错过了什么?谢谢。

更新

即使删除strtotime后,我仍然无法获得匹配日期。我发现默认时区也影响了DateTime对象。我想出了这个:

<?php

class TimezoneLib {

    public static $defaultSystemTimezone;

    public static function init() {
        self::$defaultSystemTimezone = date_default_timezone_get();
    }

    public static function date($format, $time = false, $from_timezone = false, $to_timezone = false) {

        self::switchSystemTimezone($from_timezone);

        if (!$time) {
            $time = time();
        }

        if (($from_timezone === $to_timezone) || (!$from_timezone || !$to_timezone)) {
            return date($format, $time);
        }

        $from_tz = new DateTimeZone($from_timezone);
        $to_tz = new DateTimeZone($to_timezone);

        $dt = new DateTime($time, $from_tz);

        self::switchSystemTimezone($to_timezone);
        $offset = $to_tz->getOffset($dt);
        $convertedDate = date($format, $dt->format('U') + $offset);

        self::restoreSystemTimezone();
        return $convertedDate;
    }

    public static function switchSystemTimezone($timezone_identifier) {
        return date_default_timezone_set($timezone_identifier);
    }

    public static function restoreSystemTimezone() {
        return date_default_timezone_set(self::$defaultSystemTimezone);
    }

}

TimezoneLib::init();

$format = 'Y-m-d H:i:s';
$initialtime = '2013-06-13 12:00:00';

echo $initialtime;
echo '<br/>';

$convtime = TimezoneLib::date($format, $initialtime, 'Canada/Atlantic', 'Europe/Prague');
echo $convtime;
echo '<br/>';

echo TimezoneLib::date($format, $convtime, 'Europe/Prague', 'Canada/Atlantic');
die();

使用以下输出

2013-06-13 12:00:00
2013-06-13 19:00:00
2013-06-13 11:00:00

1 个答案:

答案 0 :(得分:1)

创建一个新的DateTime对象,而不是使用strtotime:

$date = new DateTime('your_date_here',  DateTimeZone object here);