天数组到期间

时间:2018-06-06 06:20:17

标签: php datetime period

我有一系列与以下类似的日子:

array(10) {
 [0]=>
  string(8) "01/06/18"
 [1]=>
  string(8) "02/06/18"
 [2]=>
  string(8) "03/06/18"
 [3]=>
  string(8) "11/06/18"
 [4]=>
  string(8) "12/06/18"
 [5]=>
   string(8) "13/06/18"
 [6]=>
   string(8) "14/06/18"
 [7]=>
   string(8) "15/06/18"
 [8]=>
   string(8) "16/06/18"
 [9]=>
   string(8) "20/06/18"
}

我正在尝试解决方案,以便从以下几天获得句点的日期:

Period 1:
    01/06/18 - 03/06/18
Period 2:
    11/06/18 - 16/06/18
Period 3:
    20/06/18 - 20/06/18

什么是最短的方式!?

这是我正在尝试的但没有成功:

注意:我正在更改日期格式以符合Y-m-d

    private function SetPeriods($days)
{
    // check if input is empty
    if(count($days) == 0) return array();

    // output to fill
    $ranges = array();

    // order dates keys in order to have the first date in temporary order
    ksort($days);

    // get first and last day
    $firstday = key($days);
    end($days);
    $lastday = key($days);

    // get the type of first day (actually the current day where we looks)
    $current_type = $days[$firstday];

    // using datetime object for easy step of 1 day
    $datetime = new DateTime($days[$firstday]);
    $datetime->setTime(9,0,0); // avoid time problems at midnight (it's needed?)

    // do the first step outside the while
    $datetime->add(new DateInterval('P1D'));

    // store old value of day
    $oldday = $firstday;

    // build the first range
    $ranges[] = array($firstday,null,$current_type);

    while(($day = $datetime->format('Y-m-d')) <= $lastday) {

        // if there are holes, fill it with null
        if(!isset($days[$day])) {
            $days[$day] = null;
        }

        // check if type has changed (=>need new range)
        if(($days[$day] !== $current_type)) {
            $ranges[count($ranges)-1][1] = $oldday;
            $ranges[] = array($day,null,$days[$day]);
            $current_type = $days[$day];
        }

        // store previous day
        $oldday = $day;
        // next day
        $datetime->add(new DateInterval('P1D'));

    }

    // complete the last range
    $ranges[count($ranges)-1][1] = $lastday;

    // remove range of holes
    foreach($ranges as $k=>$range) {
        if(is_null($range[2])) {
            unset($ranges[$k]);
        }
    }

    return $ranges;
}

问题是现在我只得到一个日期我不知道问题是什么不能解决它

2 个答案:

答案 0 :(得分:1)

这是一种方法,不确定它是否是最短的。

我转换为Unix时间,如果Unix时间与之前的Unix时间相比超过一天,我会创建一个新的子阵列来存储它。

然后res数组将在Unix时间内保存句点 我循环并转换为日期仅获取最小值和最大值。

$i =-1;
$prev =0;
$format = "d/m/y";

Foreach($arr as $val){
    $dt = date_create_from_format ($format , $val);
    $unix = date_timestamp_get($dt);

    If($unix -$prev > 86400) $i++;
    $res[$i][] = $unix;
    $prev = $unix;
}

Foreach($res as $period){
    If(count($period) >1){
        $periods[] = date($format, min($period)) . " - " . date($format, max($period));
    }Else{
        $periods[] = date($format, min($period));
    }
}
Var_dump($periods);

https://3v4l.org/gHDC0


现在我想起来了,它可以稍微缩短一点 我跳过最后一个foreach因为我可以在主循环中动态执行它,除了循环之后完成的最后一项。

https://3v4l.org/buaCN

$i =-1;
$prev =0;
$format = "d/m/y";

Foreach($arr as $val){
    $dt = date_create_from_format ($format , $val);
    $unix = date_timestamp_get($dt);

    If($unix -$prev > 86400){
        $i++;
        If($i>0){
            If(count($res[$i-1]) >1){
                $periods[] = date($format, min($res[$i-1])) . " - " . date($format, max($res[$i-1]));
            }Else{
                $periods[] = date($format, min($res[$i-1]));
            }
        }
    }
    $res[$i][] = $unix;
    $prev = $unix;
}

If(count(end($res)) >1){
    $periods[] = date($format, min(end($res))) . " - " . date($format, max(end($res)));
}Else{
    $periods[] = date($format, min(end($res)));
}

Var_dump($periods);

答案 1 :(得分:-1)

此逻辑基于10天1-9,10-19,20-31期间

      $daysArray = array(
            0=> "01/06/18",
            1=> "02/06/18",
            2=> "03/06/18",
            3=> "11/06/18",
            4=> "12/06/18",
            5=> "13/06/18",
            6=> "14/06/18",
            7=> "15/06/18",
            8=> "16/06/18",
            9=> "20/06/18"
        );
$daysArray1 = $daysArray2 = $daysArray3 = array();
foreach ($daysArray as $key=>$value) {
    $expValue = $value;
    $val = explode('/',$expValue);
    if($val[0]<9) {
        $daysArray1[] = $value;
    }
    if($val[0]>9 && $val[0]<19) {
        $daysArray2[] = $value;
    }
    if($val[0]>19 && $val[0]<=31) {
        $daysArray3[] = $value;
    }
}
echo 'Period 1: <br />';
echo min(array_values($daysArray1)).'-'.max(array_values($daysArray1));

echo '<br /> Period 2: <br />';
echo min(array_values($daysArray2)).'-'.max(array_values($daysArray2));

echo '<br /> Period 3: <br />';
echo min(array_values($daysArray3)).'-'.max(array_values($daysArray3));