При использовании функции как date
и strtotime
, PHP преобразует входы, которые поставляют в соответствии с конфигурацией date.timezone
в PHP, который не может быть UTC. Поэтому перед тем, как выполнить преобразование, важно проверить или явно задать часовой пояс.
$date = "30 Aug 2016 1:00 pm";
date_default_timezone_set("UTC");
var_dump(date_default_timezone_get()); // gives us "UTC"
var_dump(date("Y-m-d H:i:s", strtotime($date))); // 2016-08-30 13:00:00
var_dump(date("Y-m-d H:i:s", strtotime($date . "+5:30"))); // 2016-08-30 07:30:00
Итак, теперь вам интересно, почему вы только что вернулись вовремя 5 часов и 30 минут. Ну, если вы посмотрите на фактическую временную метку Unix от strtotime
, то правда раскрывается о том, что делают date
и strtotime
.
var_dump(strtotime("30 Aug 2016 1:00 pm"), strtotime("30 Aug 2016 1:00 pm +5:30"));
Это дает ...
int(1472562000)
int(1472542200)
В первом случае strtotime
принимает входную строку "30 Aug 2016 1:00 pm"
и преобразует его в метку времени Unix при условии, что мы находимся в настоящее время в формате UTC. Во втором случае он принимает строку ввода "30 Aug 2016 1:00 pm +5:30"
, которая уже имеет смещение по часовой стрелке +5: 30. Таким образом, предполагается, что мы достигли 1:00 вечера в GMT + 0530, и он пытается преобразовать это обратно в UTC (i.е +0000), имея в виду его теперь нужно вычесть 5 часов и 30 минут, чтобы добраться до UTC, который дает вам "30 Aug 2016 7:30 am"
Это проще, чтобы избежать всего этого путаницы при использовании DateTime
, потому что вы можете явно указать часовой пояс или GMT и не подлежат неявному изменению часового пояса. Кроме того, важно отметить, что в PHP часовой пояс больше, чем просто смещение по GMT. PHP использует Olson Timezone Database для надежной и точной конвертации информации о дате/времени в разных часовых поясах, так как смещения GMT могут меняться в течение года в разных часовых поясах.
// DateTime doesn't try to convert this because you told it what the timezone is
$dt = new DateTime("30 Aug 2016 1:00 pm", new DateTimezone("UTC"));
// now lets try with the offset
$dt->setTimezone(new DateTimezone("Asia/Kolkata"));
var_dump($dt->format("j M Y g:i a")); // "30 Aug 2016 6:30 pm"
Обратите внимание, что вам не нужно на самом деле обходиться с количеством часов/минут для добавления/вычитания. PHP показывает все, просматривая необходимую информацию о часовом поясе в базе данных. Поскольку мы правильно указали предоставленный часовой пояс и изменили часовой пояс, мы можем быть уверены, что у нас всегда есть точное время независимо от того, сколько раз мы впоследствии конвертируем между часовыми поясами. Это гораздо более надежная абстракция, чем то, что вы пытаетесь сделать.
Поскольку strtotime является Stringparser, он иногда ведет себя странно. Я бы предложил рассчитать с отметками времени, а не с датами, или использовать DateTime. В DateTime вы можете изменить часовой пояс и получить требуемый результат. –