从DatePeriod中删除DateTime / Object

时间:2017-09-12 11:13:03

标签: php date datetime time

我试图创建一个过滤器,如果在列表中找不到天数(星期一,星期二等),我希望从我的DatePeriod中删除该特定的DateTime。这是我可以说,我周一和周二工作。如果您发现当天是星期四,请继续退出此循环并且不要将其包括在内。

然而,我似乎无法做到这一点,因为当我遍历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;
    }

然后关闭结束标记(我没有把它包含在这里,因为我做了其他一些事情。

从上面的代码中,我收到以下错误: &#34;致命错误:未捕获错误:无法使用DatePeriod类型的对象作为数组&#34;

有解决方法吗?

澄清:$ e_d_w_p_w是&#34;每周工作的员工天数&#34;
$ e_d_w_p_w的格式如此&#34;星期一;星期二;&#34;等

2 个答案:

答案 0 :(得分:1)

问题是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);

Demo

另外,我认为它可能会更清晰(更快;尽可能避免使用正则表达式)将$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 :(得分:0)

我正在研究在DatePeriod内的某些天内进行迭代的方法,而Google带领我来到了这里。我最终为此写了一堂课,希望对OP有帮助。

DatePeriod_Filter gist

要满足OP的需求,您可以像这样使用它:

$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
}