PHP - 按月的日期范围

时间:2017-04-12 08:44:03

标签: php arrays date date-range php-carbon

我有一个日期范围,我需要按月分组,但我想继续开始日期和结束日期。到目前为止,我有这个:

    $interval['from'] = '2017-01-02 00:00:00';
    $interval['to'] = '2017-02-06 23:59:59';

    $start = Carbon::createFromFormat('Y-m-d H:i:s', $interval['from'])->startOfMonth();
    $end = Carbon::createFromFormat('Y-m-d H:i:s', $interval['to'])->startOfMonth()->addMonth();
    $separate = CarbonInterval::month();
    $period = new \DatePeriod($start, $separate, $end);

    foreach ($period as $dt) {
        dump($dt);
    }

但结果我得到了:

Carbon\Carbon(3) {
   date => "2017-01-01 00:00:00.000000" (26)
   timezone_type => 3
   timezone => "Europe/Prague" (13)
}
Carbon\Carbon(3) {
   date => "2017-02-01 00:00:00.000000" (26)
   timezone_type => 3
   timezone => "Europe/Prague" (13)
}

按月分组,但我需要整个月,我的意思是

2017-01-02 00:00:002017-01-31 23:59:59

2017-02-01 00:00:002017-02-06 23:59:59

输出:

$array = [
    0 => [
        'from' => '2017-01-02 00:00:00',
        'to' => '2017-01-31 23:59:59'
    ],
    1 => [
        'from' => '2017-02-01 00:00:00',
        'to' => '2017-02-06 23:59:59'
    ]
];

获得它的最简单方法是什么?

编辑:这是一个有点修改的Carbon版本的接受答案,也许有人需要它:

$interval['from'] = '2017-01-02 00:00:00';
$interval['to'] = '2017-04-08 23:59:59';

$interval_from = Carbon::createFromFormat('Y-m-d H:i:s', $interval['from']);
$interval_to = Carbon::createFromFormat('Y-m-d H:i:s', $interval['to']);

$result = [];
foreach (range($interval_from->month, $interval_to->month) as $x) {
    $to = $interval_from->copy()->endOfMonth();

    if ($x == $interval_to->month) {
        $result[] = ["from" => $interval_from, "to" => $interval_to];
    } else {
        $result[] = ["from" => $interval_from, "to" => $to];
    }
    $interval_from = $to->copy()->addSecond();

}

1 个答案:

答案 0 :(得分:1)

PHP code demo

尝试此解决方案,您可以从一个月更改为另一个月(而非一年),然后检查。冗长的解决方案,但希望能够正确地进行解释。

<?php

ini_set('display_errors', 1);

$from=$interval['from'] = '2017-01-02 00:00:00';
$interval['to'] = '2017-03-07 23:59:59';


$month1=date("m",  strtotime($interval['from']));
$month2=date("m",  strtotime($interval['to']));

$result=array();


foreach(range($month1, $month2) as $x)
{
    $dateTimeObj= new DateTime($from);
    $dayDifference=($dateTimeObj->format('d')-1);

    $dateTimeObj= new DateTime($from);
    $dateTimeObj->add(new DateInterval("P1M"));
    $dateTimeObj->sub(new DateInterval("P".$dayDifference."DT1S"));
    $to= $dateTimeObj->format("Y-m-d H:i:s");

    if($x==$month2)
    {
        $dateTimeObj= new DateTime($interval['to']);
        $noOfDays=$dateTimeObj->format("d");
        $dateTimeObj->sub(new DateInterval("P".($noOfDays-1)."D"));
        $from=$dateTimeObj->format("Y-m-d H:i:s");
        $result[]=array("from"=>$from,"to"=>$interval['to']);
    }
    else
    {
        $result[]=array("from"=>$from,"to"=>$to);
    }
    //adding 1 second to $to for next time to be treated as $from
    $dateTimeObj= new DateTime($to);
    $dateTimeObj->add(new DateInterval("PT1S"));
    $from= $dateTimeObj->format("Y-m-d H:i:s");
}
print_r($result);