Удаление DateTime / объекта из DatePeriod

Я пытаюсь создать фильтр, в соответствии с которым, если дни (понедельник, вторник и т. Д.) Не найдены в списке, я хочу, чтобы этот конкретный DateTime был удален из моего DatePeriod. Это так, что я могу сказать, я работаю в понедельник и вторник. Если вы обнаружите, что это четверг, продолжайте этот цикл и не включайте его.

Тем не менее, я не могу сделать это, потому что, когда я перебираю DatePeriod, я не могу ничего сбросить, так как он не считается массивом. Есть ли способ сделать это? Код можно найти ниже:

//Get all the start and end dates of the holidays (This will be run iteratively)
$get_st_date = $row['h_s_date'];
$get_end_date = $row['h_e_date'];
//Convert them to approprariate format to be used with DatePeriod
$get_begin = new DateTime( "$get_st_date" );
$get_end = new DateTime( "$get_end_date");

//Add an extra day or else it will be omitted from the following process.
$get_end = $get_end->add(new DateInterval('P1D'));
//Count per day
$get_interval = DateInterval::createFromDateString('1 day');
$get_period = new DatePeriod($get_begin, $get_interval, $get_end);
//Iteration Count
$iter = 0;
foreach($get_period as $get_dt){
//Find if date is  Saturday or Sunday. If it is, break that current loop.
$iter++;
$str_result = $get_dt->format('l');
if($str_result == "Saturday") {continue;}
elseif($str_result == "Sunday") {continue;}
elseif(!preg_match("($str_result)", $e_d_w_p_w)){
echo "<br>Don't count this day" . $str_result;
unset($get_period[$iter]);
continue;
}

Затем закройте конечные теги (я не включил их здесь, как делаю некоторые другие вещи.

Из приведенного выше кода я получаю следующую ошибку:
«Неустранимая ошибка: необработанная ошибка: невозможно использовать объект типа DatePeriod в качестве массива»

Есть ли обходной путь к этому?

Для пояснения: $ e_d_w_p_w — это «Работающие дни в неделю»
$ e_d_w_p_w отформатирован так: «Понедельник; Вторник;» так далее

2

Решение

Проблема в том, что DatePeriod является не массив, как говорит ошибка. Он просто имеет свойства, необходимые для составления списка необходимых дней, но не сохраняет их, поэтому вы не можете unset() конкретный день из списка.

Для этого вы можете создать новый массив и вместо удаления дней, не соответствующих критериям, из DatePeriod, только добавьте дни, которые делают к этому новому массиву:

<?php
$get_st_date = "2017-09-01";
$get_end_date = "2017-09-20";
//Convert them to approprariate format to be used with DatePeriod
$get_begin = new DateTime( "$get_st_date" );
$get_end = new DateTime( "$get_end_date");

//Add an extra day or else it will be omitted from the following process.
$get_end = $get_end->add(new DateInterval('P1D'));
//Count per day
$get_interval = DateInterval::createFromDateString('1 day');
$get_period = new DatePeriod($get_begin, $get_interval, $get_end);

$e_d_w_p_w = "Monday;Tuesday;";
$workDays = [];
//Iteration Count
$iter = 0;
foreach($get_period as $get_dt) {
//Find if date is  Saturday or Sunday. If it is, break that current loop.
$iter++;
$str_result = $get_dt->format('l');
if($str_result == "Saturday") {continue;}
elseif($str_result == "Sunday") {continue;}
elseif(preg_match("($str_result)", $e_d_w_p_w)){
$workDays[] = $get_dt;
}
}
var_dump($workDays);

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

Кроме того, я думаю, что это может быть немного чище (и быстрее, избегайте регулярных выражений, когда это возможно) для преобразования $e_d_w_p_w в массив и проверьте, находится ли текущий день в этом массиве:

$e_d_w_p_w = "Monday;Tuesday;";
$days = explode(";", $e_d_w_p_w); // transform to an array, separating by ;
array_pop($days); // remove the last element (assuming you always have a trailing ;

а потом

elseif(in_array($str_result, $days)){
$workDays[] = $get_dt;
}
1

Другие решения

Я исследовал способы итерации в определенные дни в рамках DatePeriod, и Google привел меня сюда. В итоге я написал для него класс — надеюсь, это поможет ОП.

DatePeriod_Filter Гист

Для удовлетворения потребностей ОП вы можете использовать его следующим образом:

$e_d_w_p_w = "Monday;Tuesday;";

//Add an extra day or else it will be omitted from the following process.
$filter = new DatePeriod_Filter(
new DateTime( '2017-09-01' ),
new DateInterval( 'P1D' ),
new DateTime( '2017-09-20 + 1 day' )
);

foreach( explode( ';', strtolower( trim( $e_d_w_p_w, ';' ) ) ) as $day )
$filter->$day();

foreach( $filter as $date )
{
// do something here
}
0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector