Я сохраняю время, используя целые временные метки Unix для каждого бронирования в моей базе данных. У меня проблема с тем, что мой запрос не выбирает вещи должным образом, и, похоже, выходной.
Например, на моем веб-сайте у меня есть таблица календаря, которая показывает каждый день месяца. Я использую следующий код для заполнения продуктов на каждый день:
$sql = "select b.*, p.name as p_name, p.color as p_color
from `bookings` as b
left join `products` as p on (p.id = b.id_product)
where date_format(from_unixtime(b.timestamp), '%M %e %Y') = date_format(from_unixtime(:timestamp), '%M %e %Y')
order by b.timestamp asc";
$stm = $this->app->db->prepare($sql);
$stm->bindParam(':timestamp', $this->timestamp);
$stm->execute();
$res = $stm->fetchAll();
Теперь он показывает заказы, которые я сделал на 24 января на 25-й день в моем календаре.
Проблема, похоже, заключается в этой части запроса:
where date_format(from_unixtime(b.timestamp), '%M %e %Y') = date_format(from_unixtime(:timestamp), '%M %e %Y')
Например, когда $this->timestamp = '1453698000'
(25-е) и b.timestamp = '1453618800'
(24-е), это показывает эту запись 25-го в моем календаре.
Я понятия не имею, почему это происходит. Я попытался изменить запрос date_format для использования «% d-% m-% Y», я попытался добавить «00: 00: 00», я попытался вручную установить часовой пояс в конструкции PDO, я удостоверился, что все мои часовые пояса выстроены правильно (как они есть), отображая временные метки с помощью функции PHP date ().
Почему это происходит? Любая помощь будет принята с благодарностью.
Прежде всего, вы можете отладить это более тщательно, запустив:
SELECT date_format(from_unixtime(1453698000), '%M %e %Y')
а также
SELECT date_format(from_unixtime(1453618800), '%M %e %Y')
и видеть, что выходит из каждого. Это должно выявить проблему.
Я не знаю, как вы думали, что устанавливали часовой пояс при передаче метки времени Unix, но я не думаю, что это возможно. Часовой пояс используется для вычисления местного времени и даты из общей метки времени.
Не имеет значения, в каком часовом поясе PHP считает каждую временную метку, поэтому ваши функции PHP date () совпадают. Что важно, так это часовой пояс, в котором находится ваш движок MySQL, поскольку именно здесь вы выполняете преобразование.
Я бы вычислил точную метку времени из правильной даты и времени в вашем приложении (например, 25-е в 00:00:00) и передал бы ее в запрос.
Само преобразование:
where date_format(from_unixtime(b.timestamp), '%M %e %Y') = date_format(from_unixtime(:timestamp), '%M %e %Y')
делает недействительным любой индекс на временной метке, что может привести к снижению производительности.
Было бы лучше написать это как:
WHERE b.timestamp >= :timestamp
AND b.timestamp < :timestamp + INTERVAL 1 DAY
Другие ваши варианты, чтобы изменить часовой пояс MySQL.
Других решений пока нет …