Попадает время в промежуток между двумя time или нет?

Ссылка скопирована
1 ответ

Есть таблица 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.

  • nApoBo3, можно без вычислений, но условие будет с ИЛИ.
    Интереснее когда график работы магазина разный в выходные и будни, причем, скажем, на выходных магазин открыт в полночь.
    Ну, к примеру, пн-пт - 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 &lt;= close_time) AND (localtime BETWEEN open_time AND close_time) OR (open_time &gt; close_time) AND NOT (localtime BETWEEN close_time AND open_time)

    SELECT * FROM shop WHERE (open_time &lt;= close_time) AND (localtime BETWEEN open_time AND close_time) OR (open_time &gt; 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.
    Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Дмитрий К. Ответ

    Для решения данной задачи нам необходимо написать функцию, которая будет принимать два временных промежутка в виде строк и проверять, попадает ли время в первом промежутке между временем второго промежутка.

    Ниже приведен пример кода на языке PHP, который решает данную задачу:

    function isTimeBetween($timeToCheck, $startTime, $endTime) {
        $timeToCheck = strtotime($timeToCheck);
        $startTime = strtotime($startTime);
        $endTime = strtotime($endTime);
     
        if ($timeToCheck &gt;= $startTime &amp;&amp; $timeToCheck &lt;= $endTime) {
            return true;
        } else {
            return false;
        }
    }
     
    // Пример использования функции
    $timeToCheck = &quot;15:30:00&quot;;
    $startTime = &quot;12:00:00&quot;;
    $endTime = &quot;18:00:00&quot;;
     
    if (isTimeBetween($timeToCheck, $startTime, $endTime)) {
        echo &quot;Время $timeToCheck попадает между $startTime и $endTime&quot;;
    } else {
        echo &quot;Время $timeToCheck не попадает между $startTime и $endTime&quot;;
    }

    function isTimeBetween($timeToCheck, $startTime, $endTime) { $timeToCheck = strtotime($timeToCheck); $startTime = strtotime($startTime); $endTime = strtotime($endTime); if ($timeToCheck &gt;= $startTime &amp;&amp; $timeToCheck &lt;= $endTime) { return true; } else { return false; } } // Пример использования функции $timeToCheck = &quot;15:30:00&quot;; $startTime = &quot;12:00:00&quot;; $endTime = &quot;18:00:00&quot;; if (isTimeBetween($timeToCheck, $startTime, $endTime)) { echo &quot;Время $timeToCheck попадает между $startTime и $endTime&quot;; } else { echo &quot;Время $timeToCheck не попадает между $startTime и $endTime&quot;; }

    В данном коде мы используем функцию isTimeBetween, которая принимает три параметра: время, которое нужно проверить ($timeToCheck), начальное время промежутка ($startTime) и конечное время промежутка ($endTime).

    Функция сначала преобразует переданные строки времени в формат timestamp с помощью функции strtotime. Затем она сравнивает время $timeToCheck с $startTime и $endTime. Если время $timeToCheck находится между $startTime и $endTime, то функция вернет true, иначе false.

    Пример использования функции показывает, как можно проверить, попадает ли время 15:30:00 между 12:00:00 и 18:00:00. В зависимости от результата функции будет выведено соответствующее сообщение.

    Таким образом, данный код поможет решить задачу определения попадания времени в заданный промежуток.

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно