Библиотека для "рабочих часов" магазина

Администратор указывает время работы магазина (9:00 - 18:00 местное время, без даты), в БД оно хранится как UTC.

Пользователь передаёт местное время (Y-m-d H:i), необходимо вернуть открыт ли магазин. Конвертирую UTC в локальное время и пытаюсь сравнить открыт ли магазин. Проблемы начинаются когда магазин, например, открывается в 21:00, закрывается в 03:00.

Возможно есть готовая библиотека или примеры проектов с такой же задачей?


Ответы (2 шт):

Автор решения: Эникейщик

В чем проблема-то? Тоже мне бином ньютона. Сначала сравнить время открытия и закрытия. Если открывается раньше, чем закрывается (9:00 vs. 18:00), то проверять так. А если открывается позже, чем закрывается (21:00 vs. 3:00), то проверять наоборот.

→ Ссылка
Автор решения: Dmitrii Sedov

Мы просто знаем время работы магазина в часах, например 6. Далее указываем время открытия магазина на текущий день, после добавляем время работы "PT6H", получаем время закрытия магазина. Так как все 3 даты объекты DateTime, то их можно сравнивать как есть. На выходе проверяем попадает ли дата в текущий промежуток времени. В результате нам не надо определять это следующий или предыдущий день, класс сам сделает данную работу. Далее просто добавьте зону и всё.

UPD Дополнил ответ

UPD2 Ещё дополнил

function isOpen($date) {
    $userDate = new \DateTime($date);
    $currentDay = $userDate->format('Y-m-d');
    $openDate = new \DateTime(date("$currentDay 07:00"));
    $open = new \DateTime($openDate->format('Y-m-d H:i'));

    $openDate->add(new \DateInterval('PT6H'));

    $close = new \DateTime($openDate->format('Y-m-d H:i'));
    return ($close->format('H:i') > $open->format('H:i'))
        ? ($userDate >= $open && $userDate < $close)
        : ($close->format('H:i') > $userDate->format('H:i') && $userDate->format('H:i') < $open->format('H:i'));
}

echo isOpen("2021-08-25 06:00");
→ Ссылка