PHP Как сгенерировать временные метки на таймфрейме с указанным c еженедельным расписанием? - PullRequest
0 голосов
/ 26 апреля 2020

Мне нужно найти способ генерировать временные метки между двумя датами с жестким еженедельным расписанием. (см. пример ниже)

Расписание на неделю

Mo - skip
Tu - 18.30
We - 18.30
Th - 19.30
Fr - 19.30
Sa - 14.00 & 19.30
So - 15.00

И я хочу сгенерировать все метки времени между 2020-05-01 и 2020-05-31.

Моя идея состоит в том, чтобы использовать DatePeriod для генерации всех временных отметок из каждого дня в установленный период времени. (Получите первый вторник с начальной даты, добавьте время и используйте DatePeriod, чтобы получить все вторники на таймфрейме - то есть с каждым разом в недельном расписании). Затем я мог бы объединить массивы и отсортировать их.

Мне интересно, есть ли более простой способ сделать это? Есть идеи?

1 Ответ

0 голосов
/ 29 апреля 2020

Время недели можно сохранить в массиве с выражениями относительной даты.

$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 может использоваться для достижения желаемого формата даты.

...