Время недели можно сохранить в массиве с выражениями относительной даты.
$times = [
"Tue 18:30",
"Wed 18:30",
"Thu 19:30",
"Fri 19:30",
"Sat 14:00",
"Sat 19:30",
"Sun 15:00",
];
Все это время добавляется в $ curDate, и после проверки наименьшее из этих значений равно сохранен как $ nextDate. Это продолжается некоторое время до даты окончания. Я написал функцию для этого.
function schedulePeriod(array $times, $start, $end)
{
$period = [];
$curDate = clone $start;
while(true){
$nextDate = clone $end;
foreach($times as $modifier){
$nextTime = (clone $curDate)->modify($modifier);
if($nextTime > $curDate AND $nextTime < $nextDate){
$nextDate = $nextTime;
}
}
if($nextDate >= $end) break;
$period[] = $nextDate;
$curDate = $nextDate;
}
return $period;
}
Результатом этой функции является массив объектов datetime.
$start = date_create("2020-05-01 00:00");
$end = date_create("2020-06-01 00:00");
$period = schedulePeriod($times, $start, $end);
echo '<pre>';
var_export($period);
Вывод (уменьшенный):
array (
0 =>
DateTime::__set_state(array(
'date' => "2020-05-01 19:30:00.000000",
'timezone_type' => 3,
'timezone' => "Europe/Berlin",
)),
1 =>
DateTime::__set_state(array(
'date' => "2020-05-02 14:00:00.000000",
'timezone_type' => 3,
'timezone' => "Europe/Berlin",
)),
2 =>
DateTime::__set_state(array(
'date' => "2020-05-02 19:30:00.000000",
'timezone_type' => 3,
'timezone' => "Europe/Berlin",
)),
3 =>
DateTime::__set_state(array(
'date' => "2020-05-03 15:00:00.000000",
'timezone_type' => 3,
'timezone' => "Europe/Berlin",
)),
Метод формата dateTime может использоваться для достижения желаемого формата даты.