DateTime和DateTimeZone的奇怪行为


Strange behaviour with DateTime and DateTimeZone

这是我上一个问题的后续问题。应用程序是javascript/php。在Javascript中,我得到了本地时间戳和时区偏移量:

var timestamp = new Date().getTime();
var tzoffset = new Date().getTimezoneOffset();

我正在伦敦测试这个,我传入的时间代表格林尼治时间15:30:00。

然后,我将这些传递给服务器上的php脚本,该脚本需要将此时间戳格式化为H:MM:SS(即php的format('h:i:s', $time)。我在PHP中开始使用以下代码:
$dt = new DateTime();
$dt->setTimestamp($timestamp / 1000);  //javascript includes milliseconds, php doesn't
echo $dt->format('h:i:s');

这将产生07:30:00的输出—它是相同的时间点,但使用服务器的时区(服务器位于加利福尼亚)。

然后我使用这个问题中的技巧来获取时区并设置该时区

$tz = timezone_name_from_abbr(null, $tzoffset * 60, true);  //javascript's offset is in seconds
if($tz === false) $tz = timezone_name_from_abbr('', $tzoffset * 60, false);
$dt = new DateTime(null, new DateTimeZone($tz));
$dt->setTimestamp($timestamp / 1000);
echo $dt->format('h:i:s');

这产生了一个相当奇怪的02:30:00结果。

然后我把上面的代码改成:

$dt = new DateTime(null, new DateTimeZone('Europe/London'));
$dt->setTimestamp($timestamp / 1000);
echo $dt->format('h:i:s');

结果为03:30:00

如何让服务器根据客户端提供的信息输出15:30:00 ?

编辑:谢谢,@MarkM,这是相当愚蠢的我-但这仍然不能完全解决问题,因为这个代码:

$tz = timezone_name_from_abbr(null, $tzoffset * 60, true);  //javascript's offset is in seconds
if($tz === false) $tz = timezone_name_from_abbr('', $tzoffset * 60, false);
$dt = new DateTime(null, new DateTimeZone($tz));
$dt->setTimestamp($timestamp / 1000);
echo $dt->format('h:i:s');

现在产生14:30:00,也就是说,它没有考虑DST。有办法解决这个问题吗?

EDIT 2:我忘记了javascript的getTimezoneOffset返回逆(即GMT从当前时间多少分钟)。我在EDIT的代码顶部添加了这一行,现在它正常工作了:

$tzoffset = -$tzoffset;

将小时格式设置为24小时格式,使用大写h。

'h:i:s'改为'H:i:s'