#php #mysql #mysqli #time #pdo
#php #mysql #mysqli #время #pdo
Вопрос:
Итак, я создаю систему доставки еды. Я хочу проверить, занято ли время. Проблема в том, что существует длительность, связанная с некоторым временем. Это довольно легко сделать, если длительности нет.
ПРИМЕР РАБОЧЕГО КОДА:
Например, вот моя deliveries
таблица:
---- --------------- --------------- ----------
| id | delivery_date | delivery_time | duration |
---- --------------- --------------- ----------
| 1 | 2018-02-18 | 10:30:00 | null |
---- --------------- --------------- ----------
Допустим, мое выбранное время доставки равно 2018-02-18 10:30:00
, тогда оно будет принято. Код:
$deliveryDate = '2018-02-18';
$deliveryTime = '10:30:00';
$stmt = "SELECT id FROM deliveries WHERE appointment_date = :date AND appointment_time = :time";
$stmt->bindParam(':date', $deliveryDate);
$stmt->bindParam(':time', $deliveryTime);
$stmt->execute();
$result = $stmt->fetch();
if($result) {
echo 'Sorry, this is already taken!';
}
Этот код работает.
НЕ РАБОЧИЙ ПРИМЕР КОДА:
Я пытаюсь выяснить, если я изменю значение duration
с null
на 40
(40 минут), его нужно будет заблокировать 2018-02-18 10:30:00 to 11:10:00
.
Допустим, длительность равна 40 (минутам) и delivery_time
равна 11:05:00
. Он должен блокировать его.
---- --------------- --------------- ----------
| id | delivery_date | delivery_time | duration |
---- --------------- --------------- ----------
| 1 | 2018-02-18 | 10:30:00 | 40 |
---- --------------- --------------- ----------
$deliveryDate = '2018-02-18';
$deliveryTime = '11:05:00';
$stmt = "SELECT id FROM deliveries WHERE appointment_date = :date AND appointment_time = :time";
$stmt->bindParam(':date', $deliveryDate);
$stmt->bindParam(':time', $deliveryTime);
$stmt->execute();
$result = $stmt->fetch();
if($result) {
echo 'Sorry, this is already taken!';
}
Как я могу заставить его учитывать продолжительность?
Комментарии:
1. Что вы пробовали до сих пор? Кажется простым случаем установки минимального (
delivery_time
) и максимального (плюсduration
) времени.
Ответ №1:
Если вы объедините столбец даты и времени в a datetime
, вы можете использовать timestampadd()
его для добавления продолжительности, а затем проверить, находятся ли заданные дата и время в периоде.
SELECT id
FROM deliveries
WHERE cast(concat(delivery_date, ' ', delivery_time) AS datetime) <= cast(concat(:date, ' ', :time) AS datetime)
AND timestampadd(minute, duration, cast(concat(delivery_date, ' ', delivery_time) AS datetime)) > cast(concat(:date, ' ', :time) AS datetime);
Вы могли бы облегчить себе жизнь, если бы просто использовали datetime
здесь два s вместо того, чтобы разбивать его на три столбца. Тогда вы также можете воспользоваться индексами.
Комментарии:
1. Потеря возможности использовать индексы (если они, конечно, есть) может иметь огромное значение с точки зрения производительности.