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


Changing date and time between timezones

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

/**
 * 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,表示时间没有变化。

好的,试试这个:

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为你做所有的艰苦工作;-)

看到它工作

如果您偶然发现这一点,现在可以使用 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 
}