在PHP中将日期时间字符串转换为不同时区

5

好的,我有以下代码:

$from = "Asia/Manila";
$to = "UTC";
$org_time = new DateTime("2012-05-15 10:50:00");
$org_time = $org_time->format("Y-m-d H:i:s");
$conv_time = NULL;

$userTimezone = new DateTimeZone($from);
$gmtTimezone = new DateTimeZone($to);
$myDateTime = new DateTime($org_time, $gmtTimezone);
$offset = $userTimezone->getOffset($myDateTime);
$conv_time = date('Y-m-d H:i:s', $myDateTime->format('U') + $offset);
echo $conv_time;

使用这段代码,我想将2012-05-15 10:50:00转换为UTC和-8时区(我使用的是America/Vancouver),但它给我奇怪的结果。
Asia/Manila > UTC  
2012-05-15 19:50:00 = the correct is 2012-05-15 02:50

并且针对美国/温哥华地区

Asia/Manila > America/Vancouver 
2012-05-16 02:50:00 = the correct is 2012-05-14 19:50

我做错了什么?
3个回答

14

你正在把事情复杂化。要在不同的时区之间进行转换,你只需要创建一个带有正确源时区的DateTime对象,然后通过setTimeZone()设置目标时区即可。

$src_dt = '2012-05-15 10:50:00';
$src_tz =  new DateTimeZone('Asia/Manila');
$dest_tz = new DateTimeZone('America/Vancouver');

$dt = new DateTime($src_dt, $src_tz);
$dt->setTimeZone($dest_tz);

$dest_dt = $dt->format('Y-m-d H:i:s');

是的,谢谢你。抱歉我一直在用困难的方式尝试自己解决问题。 - Netorica

2
不要使用getOffset并自己计算,你应该使用setTimezone进行显示。请参考setTimezone
<?php
function conv($fromTime, $fromTimezone, $toTimezone) {

    $from = new DateTimeZone($fromTimezone);
    $to = new DateTimeZone($toTimezone);

    $orgTime = new DateTime($fromTime, $from);
    $toTime = new DateTime($orgTime->format("c"));
    $toTime->setTimezone($to);
    return $toTime;
}

$toTime = conv("2012-05-15 10:50:00", "Asia/Manila", "UTC");
echo $toTime->format("Y-m-d H:i:s");

// you can get 2012-05-15 02:50:00

echo "\n";

$toTime = conv("2012-05-16 02:50:00", "Asia/Manila", "America/Vancouver");
echo $toTime->format("Y-m-d H:i:s");

// you can get 2012-05-15 11:50:00

echo "\n";

日期格式 "Y-m-d H:i:s" 将使用当前本地时区(从 php.ini 或您的 ini_set 中获取)显示,如果要带有时区,请使用格式 "c" 或 "r"


1

从结果的快速扫描来看,似乎你需要减去偏移量而不是加上它。这是有道理的:比如你在GMT-5时区,想要将你的时间转换为GMT时区。你不应该减去5个小时(时间+偏移量),而应该加上5个小时(时间-偏移量)。当然,我现在有点累了,所以可能想反了。


我尝试过了,当我减去偏移量时,它与UTC是正确的,但问题是当我执行类似于Asia/Manila > America/Vancouver这样的操作时,它们变得相同了。 - Netorica
你的意思是它们加起来等于0吗?如果是这样,你需要先通过UTC或者将原始时区的偏移量加到目标时区的偏移量上。据我所知,你的代码只是从UTC获取了偏移量,因此当你进行UTC-8 -> UTC+8时,你最终得到的时间会减去自身。 - demize

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接