Reputation: 4808
I have a date range and I need it to group by month but I want to keep starting day and ending day. So far I have this:
$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);
}
But as result I'm getting:
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)
}
It is grouped by month but I need to get whole month period, I mean from
2017-01-02 00:00:00
to 2017-01-31 23:59:59
2017-02-01 00:00:00
to 2017-02-06 23:59:59
.
Output:
$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'
]
];
What is the easiest way to achive it?
Edit: Here is a little bit modified Carbon version of accepted answer, maybe somebody will need it:
$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();
}
Upvotes: 0
Views: 1875
Reputation: 15141
Try this solution you can change from one month to another month(not year) and then check. Lengthy solution but hopefully works correctly, putting explaination.
<?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);
Upvotes: 1