我很难使用PHP DateTime
将接收到的带有GMT -8时区(PST)的日期转换为带有GMT -7时区(PDT)的人类可读格式。
下面是一个例子:
$tz = new DateTimeZone('America/Los_Angeles');
$saleEndDate = new DateTime("2016-11-07T17:30:00-08:00");
$saleEndDate->setTimezone($tz);
echo $saleEndDate->format('Y-m-d H:i:s');
以上代码的输出为:2016-11-07 17:30:00。但是,它应该显示2016-11-07 18:30:00,因为America/Los_Angeles
现在是夏令时(GMT -7, PDT)。
从我在DateTime文档中读到的,new DateTime
命令应该能够解释字符串2016-11-07T17:30:00-08:00
具有GMT -8时区:
当time参数包含UNIX时间戳(例如946684800)或指定时区(例如2010-01-28T15:00:00+02:00)时,timezone参数和当前时区将被忽略。
尽管如此,我认为DateTime
不能正确识别GMT -8。
有谁知道在时区之间正确转换需要什么方法吗?
更新:
我还尝试将DateTimeZone
作为第二个参数传递给DateTime
构造函数,但也无济于事:
$tz = new DateTimeZone('America/Los_Angeles');
$saleEndDate = new DateTime("2016-11-07T17:30:00-08:00", new DateTimeZone("America/Los_Angeles"));
$saleEndDate->setTimezone($tz);
echo $saleEndDate->format('Y-m-d H:i:s');
也不工作:
$tz = new DateTimeZone('America/Los_Angeles');
$saleEndDate = new DateTime("2016-11-07T17:30:00", new DateTimeZone("PST"));
$saleEndDate->setTimezone($tz);
echo $saleEndDate->format('Y-m-d H:i:s');
也不工作:
$tz = new DateTimeZone("PDT");
$saleEndDate = new DateTime("2016-11-07T17:30:00", new DateTimeZone("PST"));
$saleEndDate->setTimezone($tz);
echo $saleEndDate->format('Y-m-d H:i:s');
不是最好的,但这是我能想到的唯一方法
$tz = new DateTimeZone('America/Los_Angeles');
$saleEndDate = new DateTime("2016-11-07T17:30:00-08:00");
$saleEndDate->setTimezone($tz);
$stamp = $saleEndDate->format('U');
$zone = $tz->getTransitions($stamp, $stamp);
if(!$zone[0]['isdst']) $saleEndDate->modify('+1 hour');
echo $saleEndDate->format('Y-m-d H:i:s');
我在这里做的是使用DateTimeZone::getTransitions函数来确定您提供的日期是否是夏令时。如果不是,我们就加一个小时。注意这不会改变时区,它只是校正DST移位
你可以在这里看到它的作用
DateTime
正常工作。除非你所在的地区与其他地区的夏时制不同,否则America/Los_Angeles
在2016年11月6日离开了夏时制(PDT->PST)。
https://www.timeanddate.com/news/time/usa -加拿大-结束- dst - 2016. - html
从timezeonedb
你可以检查它使用的日期通过搜索数组为您的特定日期/时间(Machavity做了),并得到的事实,它不是在夏令时,然后继续手动修改它。这不是一个答案,因为它最终会失败,除非你手动添加一个截止时间来停止手动校正。
检查你的日期周围的过渡日期显示:
date_default_timezone_set('America/Los_Angeles');
$theDate = new DateTime("2016-11-07T17:30:00",new DateTimeZone("America/Los_Angeles"));
$theDateBefore = new DateTime("2016-03-01");
$theDateAfter = new DateTime("2017-03-15");
echo "<pre>";
print_r( $theDate->getTimezone()->getTransitions(
$theDateBefore->getTimestamp(),$theDateAfter->getTimestamp()));
echo "</pre>";
导致数组为4:
Array
(
[0] => Array
(
[ts] => 1456819200
[time] => 2016-03-01T08:00:00+0000
[offset] => -28800
[isdst] =>
[abbr] => PST
)
[1] => Array
(
[ts] => 1457863200
[time] => 2016-03-13T10:00:00+0000
[offset] => -25200
[isdst] => 1
[abbr] => PDT
)
[2] => Array
(
[ts] => 1478422800
[time] => 2016-11-06T09:00:00+0000
[offset] => -28800
[isdst] =>
[abbr] => PST
)
[3] => Array
(
[ts] => 1489312800
[time] => 2017-03-12T10:00:00+0000
[offset] => -25200
[isdst] => 1
[abbr] => PDT
)
)
Array[0]是在theDateBefore
时生效的时区,您可以看到更改日期对您的时区生效。
您的销售日期落在从PDT到PST的更改之后。
要让代码返回调整后的日期/时间,您需要手动更改它。按照被接受的方式去做会产生错误的结果。正如我所提到的,您需要用希望执行自定义时区的日期来包围它。