Попадает время в промежуток между двумя time или нет?
Есть таблица shop с двумя полями: open_time и close_time. Необходимо узнать открыт сейчас магазин или нет
Я пробовал через
localtime between open_time and close_time
но он судя по всему просто свапает местами, если open_time больше close_time
То есть нужно обрабатывать случай
open_time = 22:00
close_time = 5:00
Как это можно обработать?
Дополнительно:
Только через вычисление, у вас 5:00 на самом деле не 5:00, а 29:00.
Интереснее когда график работы магазина разный в выходные и будни, причем, скажем, на выходных магазин открыт в полночь.
Ну, к примеру, пн-пт - 10:00-23:00 а сб-вс - 10:00-01:00.
Тут вообще интересно. Фактически магазин не работает в суботу с полуночи до часу ночи. но работает в понедельник с полуночи до часу ночи.
В таких случаях расписание лучше задавать набором интервалов часах, минутах или обычно в секундах от полуночи понедельника.
В часах проще показывать на примере.
0-1, 10-23 - понедельник
34-47 - вторник
и т.д.
Ответы:
Да как-как? как обычно
localtime >= open_time and localtime < close_time
UPD:
Не сразу понял в чем проблема.
Речь, похоже, о заведениях типа ночных клубов, которые работают, скажем, с 22:00 до 05:00 и нужно понять попадает ли какое-то время в этот интервал, если два времени оказались по разную сторону от полуночи.
Тут спасёт сложное условие:
SELECT * FROM shop WHERE (open_time <= close_time) AND (localtime BETWEEN open_time AND close_time) OR (open_time > close_time) AND NOT (localtime BETWEEN close_time AND open_time) |
SELECT * FROM shop WHERE (open_time <= close_time) AND (localtime BETWEEN open_time AND close_time) OR (open_time > close_time) AND NOT (localtime BETWEEN close_time AND open_time)
Это замечательно работает, если ваши магазины работают каждый день по одному графику, а если нет, то нужно строить расписание на неделю. Это доволно быстро работает, если хранить расписание в отдельной таблице в виде нтервалов работы в секундах от начала недели и ссылку (многие к одному) на учреждение.
UPD2: Перенесу, пожалуй, сюда и пример с недельным расписанием из своего комментария.
Интереснее когда график работы магазина разный в выходные и будни, причем, скажем, на выходных магазин открыт в полночь.
Ну, к примеру, пн-пт - 10:00-23:00 а сб-вс - 10:00-01:00.
Тут вообще интересно. Фактически магазин не работает в суботу с полуночи до часу ночи, но работает в понедельник с полуночи до часу ночи.
В таких случаях расписание лучше задавать набором интервалов в часах, минутах или, обычно, в секундах от полуночи понедельника.
В часах проще показывать на примере.
0-1, 10-23 - понедельник
34-47 - вторник
и т.д.
По-хорошему должен быть специальный бинарный тип данных, способный хранить такие интервалы эффективно и индексировать их.
Очевидно. что для выше изложенного графика таких интервалов надо около 7+2 - по одному основному на каждый день, час после полуночи понедельника, и час после полуночи воскресенья.
Итого 9 интервалов на магазин, если без перерывов. С обеденными перерывами будет 16 интервалов на магазин. В любом случае не критично. Просто нужно задавать реальное расписание магазина в формализованной форме (какой-то формулой) прямо в записи об этом магазине, а в таблицу с интервалами просто кэшировать развернутое расписание при апдейте формулы.
У нас точно также интервалами с кэшированием в отдельной таблице было устроено расписание ВУЗа и всё работало мгновенно.
- Ага, а теперь надо понимать, что сверху будет случай обратный (время открытия < время закрытия). И если есть варианты, как это можно всё связать, включая SELECT * FROM shop WHERE ..., то буду очень благодарен
- Я понял. Обновил ответ. Нужно всего лишь поменять местами время открытия и закрытия и инвертировать условие вхождения, когда полночь попадает на время работы учреждения.
- Ну так что, не устраивает чем-то ответ?
Тут надо сначала смысл разобрать. Вот как ты себе понимаешь что магазин открылся в 22.00 а закрылся в 5.00 ?
Закрылся в 5.00 утра следующего дня? Работал всего 7 часов. Это один кейс. А другой кейс - если свапнуть время - то получается что работал 15 часов. Выводы? Свапать нельзя никак.
А вот когда смысл проверки мы поймем - тогда можно и код писать. В крайнем случае - хранимую функцию написать.
- Да, всё верно, свапать никак нельзя. Проверять надо следующие кейсы
open_time > close_time. Тогда к close_time надо прибавлять 24 часа (что отдельная проблема, так как поля time)
open_time < close_time. Тут обычное сравнение between можно использоватьВсе типы данных - time, то есть при первом кейсе надо как-то привести к дате со временем, иначе + интервал 24 часа даст то же самое время
- Я-бы не стал использовать between для проверки диапазона дат. Там есть нюанс.
- mayton2019, да, нюанс со свапом дат если правая часть меньше левой (я так понимаю, ты это имел ввиду). Но вопрос остаётся открытым, как это можно сделать
- arklight, нет я имел в виду другое. Открытый, полузакрытый и закрытый интервал. Это из математики. Between моделирует интервал в котором включены точки A и B. Это не всегда удобно при работе со временем. Особенно со sliding window.
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Для решения данной задачи нам необходимо написать функцию, которая будет принимать два временных промежутка в виде строк и проверять, попадает ли время в первом промежутке между временем второго промежутка.
Ниже приведен пример кода на языке PHP, который решает данную задачу:
function isTimeBetween($timeToCheck, $startTime, $endTime) { $timeToCheck = strtotime($timeToCheck); $startTime = strtotime($startTime); $endTime = strtotime($endTime); if ($timeToCheck >= $startTime && $timeToCheck <= $endTime) { return true; } else { return false; } } // Пример использования функции $timeToCheck = "15:30:00"; $startTime = "12:00:00"; $endTime = "18:00:00"; if (isTimeBetween($timeToCheck, $startTime, $endTime)) { echo "Время $timeToCheck попадает между $startTime и $endTime"; } else { echo "Время $timeToCheck не попадает между $startTime и $endTime"; }
В данном коде мы используем функцию isTimeBetween, которая принимает три параметра: время, которое нужно проверить ($timeToCheck), начальное время промежутка ($startTime) и конечное время промежутка ($endTime).
Функция сначала преобразует переданные строки времени в формат timestamp с помощью функции strtotime. Затем она сравнивает время $timeToCheck с $startTime и $endTime. Если время $timeToCheck находится между $startTime и $endTime, то функция вернет true, иначе false.
Пример использования функции показывает, как можно проверить, попадает ли время 15:30:00 между 12:00:00 и 18:00:00. В зависимости от результата функции будет выведено соответствующее сообщение.
Таким образом, данный код поможет решить задачу определения попадания времени в заданный промежуток.