PHP时区偏移不正确


PHP timezone offset incorrect

以下PHP代码:

function serverTimeZone_offset($userTimeZone)
{
    $userDateTimeZone = new DateTimeZone($userTimeZone);
    $userDateTime     = new DateTime("now", $userDateTimeZone);
    $serverTimeZone     = date_default_timezone_get();
    $serverDateTimeZone = new DateTimeZone($serverTimeZone);
    $serverDateTime     = new DateTime("now", $serverDateTimeZone);
    return $serverDateTimeZone->getOffset($userDateTime);
}
function getDefineTimeZone($timezone)
{
    $userDateTimeZone = new DateTimeZone($timezone);
                 return new DateTime("now", $userDateTimeZone);
}
function getServerTimeZone()
{
    $serverTimeZone     = date_default_timezone_get();
    $serverDateTimeZone = new DateTimeZone($serverTimeZone);
    return new DateTime("now", $serverDateTimeZone);
}
$userDateTime   = getDefineTimeZone('America/Curacao');
$serverDateTime = getServerTimeZone();
$timeOffset     = serverTimeZone_offset('America/Curacao');
var_dump($userDateTime);
var_dump($serverDateTime);
var_dump($timeOffset); // the seconds is incorrect ?!?!
// adding the timezone difference
$userDateTime->add(new DateInterval('PT'.$timeOffset.'S'));
var_dump($userDateTime);

将输出:

object(DateTime)[2]
  public 'date' => string '2014-10-22 17:36:39' (length=19)
  public 'timezone_type' => int 3
  public 'timezone' => string 'America/Curacao' (length=15)
object(DateTime)[3]
  public 'date' => string '2014-10-22 23:36:39' (length=19)
  public 'timezone_type' => int 3
  public 'timezone' => string 'Europe/Paris' (length=12)
int 7200
object(DateTime)[2]
  public 'date' => string '2014-10-22 19:36:39' (length=19)
  public 'timezone_type' => int 3
  public 'timezone' => string 'America/Curacao' (length=15)

这显然是不正确的。偏移量返回7200秒(仅2小时),而不是21600秒(6小时)。为什么

我认为uou误解了DateTimeZone::getOffset()的行为。如DateTimeZone php文档中所述:

此函数将日期时间参数中指定的日期/时间的偏移量返回到GMT。GMT偏移量是使用DateTimeZone对象中包含的时区信息计算的

因此,如果服务器时区是Europe/Paris,那么getOffset()将返回7200秒,因为欧洲/巴黎是GMT+01:00,而现在是夏令时间,所以是GMT+02:00。

请尝试使用以下代码:

function serverTimeZone_offset($userTimeZone)
{
    $userDateTimeZone = new DateTimeZone($userTimeZone);
    $userDateTime     = new DateTime("now", $userDateTimeZone);
    $serverTimeZone     = date_default_timezone_get();
    $serverDateTimeZone = new DateTimeZone($serverTimeZone);
    $serverDateTime     = new DateTime("now", $serverDateTimeZone);
    return $serverDateTimeZone->getOffset($userDateTime) - $userDateTimeZone->getOffset($userDateTime);
}