PHP: DateInterval каждые две недели в X дней

У меня есть дата начала и дата окончания.
Я пытаюсь получить все вторники и среды каждые две недели.

Пример:

2017-05-23 (tu)
2017-05-24 (we)

2017-06-06 (tu)
2017-06-07 (we)
...

Что я пытаюсь сделать в PHP:

$start = new FrozenTime('2017-05-23'); // Date is in this format 'cause I'll save into DB  
$endOfYear = $start->endOfYear();  

$perWeek = new \DateInterval('P14D'); // I want every 2 weeks

$periodPerWeek = new \DatePeriod($start, $perWeek, $endOfYear);  

$days = ['2', '3']; // Tuesday and Wednesday  

foreach ($periodPerWeek as $value) {
   if (in_array($value->format('N'), $days)) {
        $test[] = [
            'start' => $value
        ];    
   }
}  

Результаты:

"start": "2017-05-23",  
"start": "2017-06-06",  
"start": "2017-06-20",  

Он получает только одну дату в массиве. Мне тоже нужно в среду! Как мне это сделать?

ВАЖНО:
Датой начала не всегда будет вторник. Пользователь может выбрать дни недели, которые он хочет.

Пример: пользователь может выбирать каждый SU, WE и FR каждые две недели.

// start date example: 2017-05-20 (saturday)
// output should be like:
2017-05-22 (SU)  
2017-05-24 (WE)  
2017-05-26 (FR)  
2017-06-05 (SU)  
2017-06-07 (WE)  
2017-06-09 (FR)  
...

person Victor    schedule 24.05.2017    source источник
comment
Вы имеете в виду вторник и среду или среду и четверг?   -  person fubar    schedule 24.05.2017
comment
Ваши среды и четверги задом наперед :)   -  person Obsidian Age    schedule 24.05.2017
comment
@fubar обновил вопрос!   -  person Victor    schedule 24.05.2017
comment
@Victor Sooo, теперь вы говорите, что хотите каждое воскресенье, среду и пятницу с даты начала до конца года в одном одномерном массиве? Что происходило во вторник и среду каждые две недели? Вы уверены, что знаете, о чем просите?   -  person mickmackusa    schedule 24.05.2017


Ответы (1)


Один из способов сделать это

/**
 * @param \DateTime $start 
 * @param \DateTime $end 
 * @param array $days i.e. ['tue', 'wed', 'sat']
 * 
 * @return array
 */

function every_two_weeks($start, $end, $days) 
{
    $dates = [];

    $mon = new DateTime('mon this week '.$start->format('Y-m-d'));

    while ($mon <= $end) {
        $of = 'this week '.$mon->format('Y-m-d');

        foreach ($days as $day) {
            $date = new DateTime("$day $of");

            if ($date < $start) {
                continue;
            }

            if ($date > $end) {
                break 2;
            }

            $dates[] = $date;
        }

        $mon->add(new DateInterval('P2W'));
    } 

    return $dates;
}

Использование:

$start = new DateTime('2017-05-23');
$end = new DateTime('2017-06-21');

$dates = every_two_weeks($start, $end, ['tue', 'wed', 'sat']);

Выход:

2017-05-23 Tue
2017-05-24 Wed
2017-05-27 Sat
2017-06-06 Tue
2017-06-07 Wed
2017-06-10 Sat
2017-06-20 Tue
2017-06-21 Wed

демонстрация 3v4l

person peterm    schedule 24.05.2017