Всем привет, подскажите, пожалуйста, сломал всю голову себе, как решить задачу. Есть календарь для бронирования, в базе MySQL хранится информация о занятом времени (timestamp поля start и end). Задача- вывести доступное к бронированию время (таймслоты заданного размера с шагом по 30 минут). Например: берём день с 7:00 до 19:00, в этом дне занято с 7:30 до 9:00 и с 14:00 до 17:00 и нужно вывести доступное для бронирования время(например 1.5 часа с шагом в 30 минут). Должно вывестись: 9:00-10:30; 9:30-11:00; 10:00-11:30; 10:30-12:00; 11:00-12:30; 11:30-13:00; 12:00-13:30; 12:30-14:00; 17:00-18:30; 17:30-19:00
Присоединяюсь к вопросу. P.S. Зачем реальное время хранить в БД? Возьмите точку отсчета и нумеруйте «слоты»
В базу попадают данные извне о занятом времени. То есть база занятого времени уже есть, задача с учётом этого вывести свободные слоты
В базу должно попадать то, что вам нужно! Когда я заглядывал в БД нашего сервиса бронирования, там реальное время только для информационных целей хранилось, а не для выстраивания списка занятости и т.п.
В базе уже есть данные о занятом времени из другого календаря. Тут задача выводить свободные таймслоты и не хранить все время в базе, а передавать также только занятое время.
PHP: <?php $date = '2020-11-16'; $work_start = $date.' 07:00:00'; $work_end = $date.' 18:59:59'; $wstart = date_format(date_create($work_start), 'U'); $wstop = date_format(date_create($work_end), 'U'); $timeslots = range($wstart, $wstop - 3600, 1800); //$sql = "SELECT UNIX_TIMESTAMP(`start`) AS `start`, UNIX_TIMESTAMP(`end`) AS `end` //FROM `tablename` //WHERE DATE(`start`) = '$date' //ORDER BY `start` ASC"; $db_result = array( array('start' => 1605504600, 'end' => 1605509999), array('start' => 1605528000, 'end' => 1605538799) ); // на эту дату занято с 07:30:00 до 08:59:59 и с 14:00:00 до 16:59:59 echo '<pre>'; foreach($timeslots as $utime) { echo date('H:i', $utime).' - '. date('H:i', $utime + 5400); $status = 'свободно'; foreach($db_result as $occupied) { if($utime >= $occupied['start'] && $utime < $occupied['end'] || $utime + 5399 >= $occupied['start'] && $utime + 5399 < $occupied['end']) { $status = 'занято'; } } echo ' '.$status.'<br />'; } ?>
Вывод: Код (Text): 07:00 - 08:30 занято 07:30 - 09:00 занято 08:00 - 09:30 занято 08:30 - 10:00 занято 09:00 - 10:30 свободно 09:30 - 11:00 свободно 10:00 - 11:30 свободно 10:30 - 12:00 свободно 11:00 - 12:30 свободно 11:30 - 13:00 свободно 12:00 - 13:30 свободно 12:30 - 14:00 свободно 13:00 - 14:30 занято 13:30 - 15:00 занято 14:00 - 15:30 занято 14:30 - 16:00 занято 15:00 - 16:30 занято 15:30 - 17:00 занято 16:00 - 17:30 занято 16:30 - 18:00 занято 17:00 - 18:30 свободно 17:30 - 19:00 свободно