改变时区之间的日期和时间

时间:2012-08-10 10:48:33

标签: php

我一直在尝试在给定日期和时间之间转换时区。
代码说的不仅仅是文字,所以这里是:

/**
 * Returns the date and time in the new timezone.
 *
 * @param string $datetime:
 *          the date and time to change between timezones
 * @param string $input_tz:
 *          the input timezone
 * @param string $output_tz:
 *          the output timezone
 * @return string The new date and time
 */
public function changeDateTime($datetime, $input_tz, $output_tz) {
    if($input_tz == $output_tz) return $datetime;
    /*
     * We calculate the hour and minute offset from GMT
     */
    date_default_timezone_set($output_tz);
    $out_dst = date('I', $datetime) ? 1 : 0;
    $out_hour_offset = intval(substr(date('O', $datetime), 1, 3)) + $out_dst;
    $out_minute_offset = intval(substr(date('O', $datetime)), - 2);

    date_default_timezone_set($input_tz);
    $in_dst = date('I', $datetime) ? 1 : 0;
    $in_hour_offset = intval(substr(date('O', $datetime), 1, 3)) + $in_dst;
    $in_minute_offset = intval(substr(date('O', $datetime)), - 2);

    /*
     * We subtract hour and minute offsets to come up with total difference
     */
    $hour_offset = $out_hour_offset - $in_hour_offset;
    $minute_offset = $out_minute_offset - $in_minute_offset;

    /*
     * Now we must take care of changing the day/month/year if necessary, as
     * well as the hour/minute for $datetime, and return that value.
     */
    $date = new DateTime($datetime);
    if($hour_offset > 0) {
        $date->add(date_interval_create_from_date_string($hour_offset . ' hours'));
        if($minute_offset > 0) $date->add(date_interval_create_from_date_string($minute_offset . ' minutes'));
    } else if($hour_offset < 0) {
        $date->sub(date_interval_create_from_date_string($hour_offset . ' hours'));
        if($minute_offset > 0) $date->sub(date_interval_create_from_date_string($minute_offset . ' minutes'));
    }
    return $date->format('Y-m-d H:i:s');
}

然而,它似乎不能很好地运作。这是我运行的代码,用于测试它是否有效:

$newdatetime = $gato->changeDateTime("2012-08-10 11:33:33", 'Europe/London', 'Europe/Madrid');
echo $newdatetime;

这是我的预期输出:2012-08-10 12:33:33
但这是我的实际输出:2012-08-10 11:33:33,这意味着时间没有变化。

2 个答案:

答案 0 :(得分:0)

好的,试试这个:

function changeDateTime($datetime, $input_tz, $output_tz) {

    // Return original string if in and out are the same
    if($input_tz == $output_tz) {
        return $datetime;
    }

    // Save current timezone setting and set to input timezone
    $original_tz = date_default_timezone_get();
    date_default_timezone_set($input_tz);

    // Get Unix timestamp based on input time zone
    $time = strtotime($datetime);

    // Start working in output timezone
    date_default_timezone_set($output_tz);

    // Calculate result
    $result = date('Y-m-d H:i:s', $time);

    // Set timezone correct again
    date_default_timezone_set($original_tz);

    // Return result
    return $result;

}

$out = changeDateTime("2012-08-10 11:33:33", 'Europe/London', 'Europe/Madrid');
var_dump($out);

不要乱搞所有那些复杂的数学,只要让PHP为你做所有艰苦的工作; - )

See it working

答案 1 :(得分:0)

如果您对此不满意,现在可以使用DateTime对象将其清理干净。

public function convertTZ($dateTimeString, $inputTZ, $outputTZ){
    $datetime = 
        \DateTime::createFromFormat('Y-m-d H:i:s', //input format - iso8601
        $dateTimeString, 
        new \DateTimeZone($inputTZ))
        ->setTimezone(new \DateTimeZone('$outputTZ'));

    //outputs a string, if you want the dateTime obj - remove ->format
    return $datetime->format('Y-m-d H:i:s'); //output format 

}