Странное поведение с DateTime и DateTimeZone

Это дополнительный вопрос к моему предыдущему . Приложение javascript/php. В Javascript я получаю локальную метку времени и смещение часового пояса:

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

Я тестирую это из Лондона, и время, которое я прохожу, соответствует 15:30:00 по Гринвичу.

Затем я передаю их в php-скрипт на сервере, который должен отформатировать эту метку времени как H:MM:SS (т.е. format('h:i:s', $time) php. Я начал в 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 на основе информации, предоставленной клиентом?

EDIT: Спасибо, @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, то есть не учитывает летнее время. Есть идеи, как это решить?

РЕДАКТИРОВАТЬ 2: я забыл, что getTimezoneOffset в javascript возвращает обратное значение (т. е. сколько минут GMT от текущего времени). Я добавил эту строку вверху кода в моем EDIT, и теперь он работает правильно:

$tzoffset = -$tzoffset;

person Aleks G    schedule 07.08.2014    source источник
comment
Изменить 'h:i:s' на 'H:i:s'   -  person Mark Miller    schedule 07.08.2014
comment
@MarkM Спасибо! Это сделало меня на шаг ближе, но все еще не совсем там. Пожалуйста, смотрите мое обновление в вопросе.   -  person Aleks G    schedule 07.08.2014
comment
@MarkM Неважно, нашел проблему - забыл, что getTimezoneOffset в javascript возвращает обратное значение. Опубликуйте свой комментарий в качестве ответа, и я приму его.   -  person Aleks G    schedule 07.08.2014


Ответы (1)


Чтобы перевести час в 24-часовой формат, используйте заглавную букву H.

Изменить 'h:i:s' на 'H:i:s'

person Mark Miller    schedule 07.08.2014