*/ public static function for_day( string $date, string $work_start_hhmm, string $work_end_hhmm, int $duration_min, int $buffer_before, int $buffer_after, int $interval_min, \DateTimeZone $tz ): array { $slots = []; $total_minutes = max( 1, $duration_min + $buffer_before + $buffer_after ); try { $cursor = new \DateTimeImmutable( $date . ' ' . $work_start_hhmm, $tz ); $end = new \DateTimeImmutable( $date . ' ' . $work_end_hhmm, $tz ); } catch ( \Throwable $e ) { return []; } while ( true ) { $slot_start = $cursor->modify( '+' . $buffer_before . ' minutes' ); $slot_end = $slot_start->modify( '+' . $duration_min . ' minutes' ); $bound_end = $slot_end->modify( '+' . $buffer_after . ' minutes' ); if ( $bound_end > $end ) { break; } $start_utc = $slot_start->setTimezone( Date_Time::utc() ); $end_utc = $slot_end->setTimezone( Date_Time::utc() ); $slots[] = [ 'start_local' => $slot_start->format( 'Y-m-d H:i' ), 'end_local' => $slot_end->format( 'Y-m-d H:i' ), 'start_utc' => $start_utc->format( 'Y-m-d H:i:s' ), 'end_utc' => $end_utc->format( 'Y-m-d H:i:s' ), ]; $cursor = $cursor->modify( '+' . max( 1, $interval_min ) . ' minutes' ); } return $slots; } }