2017-04-12 2 views
0

Ich habe einen Datumsbereich und ich brauche es nach Monat zu gruppieren, aber ich möchte Tag und Ende Tag beginnen. Bisher habe ich dies:PHP - Datumsbereich nach Monat

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

Aber als Ergebnis erhalte ich:

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

Es Monat gruppiert ist, aber ich brauche ganzen Monat Zeit zu bekommen, ich meine von

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

2017-02-01 00:00:00 zu 2017-02-06 23:59:59.

Ausgang:

$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' 
    ] 
]; 

Was ist der einfachste Weg, es zu achive?

Edit: Hier ist ein wenig modifizierte Carbon-Version von akzeptierte Antwort, vielleicht jemand wird es brauchen:

$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(); 

} 
+0

Haben Sie eine Frage: Nach dem '' -> addMonth() 'Warum hat Ihr Ergebnis, das Sie bekommen nicht' 2017-03-01'? Ich kenne Carbon nicht, aber ist das überhaupt kein Bug? – JustOnUnderMillions

+0

Ich habe es nicht bemerkt, aber wenn ich $ period Variable ablege, dann sehe ich Enddatum als '2017-03-01' also denke ich, dass' CarbonInterval' etwas Magie macht. Anyway ist kein Problem, wenn Lösung in DateTime/DateInterval/DatePeriod Klasse sein wird. –

Antwort

1

PHP code demo

diese Lösung Versuchen können Sie von 1 Monat ändern bis ein weiterer Monat (nicht Jahr) und dann überprüfen. Eine langwierige Lösung, aber hoffentlich funktioniert es richtig und stellt eine Erklärung dar.

<?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); 
+0

Danke, es funktioniert. Aber ist das nicht modern (PHP 5.6+)? –

+0

@ JaroslavKlimčík Ja, Sie sind richtig, okay, keine Probleme, ich füge eine andere Lösung für diese auch hinzu. –

+0

@ JaroslavKlimčík Ich folgte dem gleichen Ansatz, aber hier verwende ich 'DateTime'' DateInterval' inbuild Klassen von 'PHP'. –

Verwandte Themen