2012-08-10 48 views
1

我一直在尝试在给定日期和时间之间的时区之间进行转换。
代码比语言更多,所以这里是:更改时区之间的日期和时间

/** 
* 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分三十三秒
但是,这是我的实际输出:2012- 08-10 11:33:33,这意味着没有时间变化。

+0

从哪里我看到它,有一个1小时的变化 – asprin 2012-08-10 10:50:19

+0

嗯,那么你可能需要一些眼镜^^ – 2012-08-10 10:50:42

+1

为什么使这如此复杂?只需将日期/时间存储为UTC。无论你在这个星球上,这都不会改变。然后将UTC更改为适当的时区。 – 2012-08-10 10:50:48

回答

0

OK,试试这个来代替:

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

+0

太棒了!非常感谢你在那里的努力和时间。 :) 我是否必须始终返回原始时区? – 2012-08-10 12:14:49

+0

@jslvtr你不*有*返回到原来的时区,但我认为这样做是有道理的。假设你的服务器在英国,并且有人要求你把时间从美国的某个地方转换到日本的某个地方,如果你*不回到默认时区,那么剩下的时间就会执行你的脚本会认为它在日本,这可能会导致问题。 – DaveRandom 2012-08-10 12:40:00

+0

我看到了......通常我运行的使用这个函数的脚本不会介意,因为它每次调用都会处理一个日期时间更改,但它确实有意义。谢谢! – 2012-08-10 12:59:54