2016-04-23 11 views
1

Ich versuche herauszufinden, wie man insgesamt Monate zwischen zwei überlappenden Datumsbereichen erhält.PHP | Gesamtmonate von zwei überlappenden Datumsbereichen erhalten

e-g Datumsbereich von Datum-A bis Datum-B überlappt den Datumsbereich von Datum-X und Datum-Y.

_ Start|Jan - Feb - March - April ------ Nov - Dec|End (DateRange A) Start|Jan - Feb ---- Dec - Jan - Feb|End _

In zwei Datumsbereiche die Jan und Februar Monate kollidieren. Mittel von insgesamt 2 Monaten sind da. Also ich möchte diese zwei Monate in meinem Array, damit ich verschiedene Funktionen darauf anwenden kann.

e-g Ich habe diese beiden Daten

$dateRange1Start = "2015-07-01"; 
$dateRange1End = "2014-06-30"; 
=-=-=-=====-=-== 
$dateRange2Start = "2012-02-01"; 
$dateRange2End = "2014-12-31"; 

Es gibt insgesamt 6 Monate zwischen diesen beiden Datumsbereiche zu kollidieren. Ich möchte diese 6 Monate bekommen.

Ich habe versucht, in Google nach Hilfe zu suchen, aber meistens bekomme ich weniger als oder mehr als Zeichen. aber genau so. Ich habe versucht, meine eigene Logik zu implementieren, aber seine mich nicht immer überall, leider nur mehr Probleme :(

Ich versuche, um Ergebnisse zu erhalten wie diese

$collidingDates = array("2014-07","2014-08","2014-09","2014-10","2014-11","2014-12"); 

Jede Hilfe würde geschätzt. :)

== - == - == - = - == - == - == - == - == - ==

UPDATE:

Hier ist was ich habe don Bis jetzt, ja, ich bekomme Code von hier und da. und es ein wenig nach oben zu drehen, um meine Anforderungen zu erfüllen.

//Getting all Months from First Date Range 

$start = (new DateTime('2014-06-01'))->modify('first day of this month'); 

$end = (new DateTime('2015-05-06'))->modify('first day of next month'); 

$interval = DateInterval::createFromDateString('1 month'); 

$firstPeriod = new DatePeriod($start, $interval, $end); 



//Getting all Months from Second Date Range. 
$start = (new DateTime('2012-02-01'))->modify('first day of this month'); 

$end = (new DateTime('2014-12-31'))->modify('first day of next month'); 

$interval = DateInterval::createFromDateString('1 month'); 

$secondPeriod = new DatePeriod($start, $interval, $end); 


$collidingDates = array(); 

foreach ($firstPeriod as $f_dt) { 
    foreach($secondPeriod as $s_dt){ 
     if($f_dt->format("Y-m") === $s_dt->format("Y-m")){ 

      array_push($collidingDates,$f_dt->format("Y-m")); 

     } 

    } 

} 

echo "<pre>"; 
print_r($collidingDates); 

ich habe diese Ausgabe.

Array 
    (
     [0] => 2014-06 
     [1] => 2014-07 
     [2] => 2014-08 
     [3] => 2014-09 
     [4] => 2014-10 
     [5] => 2014-11 
     [6] => 2014-12 
    ) 

Aber ich glaube, ich bin immer 1 Extra Monat 2014-06, nicht sicher, wie O_o ??

+2

Haben Sie versucht, Ihre Zeiten zu DateTime-Objekten zu konvertieren und -> diff() zu verwenden? – Doug

+0

nein, weil ich nicht sicher bin, wie man Monate zwischen zwei Datumsbereichen bekommt. Ich habe Unterschiede von zwei Daten, aber nicht von zwei Datumsbereichen genommen. –

Antwort

0

Ich glaube, Sie für diese suchen:

$start = (
       new DateTime('2015-12-02')) 
       ->modify('first day of this month'); 

$end = (new DateTime('2016-05-06'))->modify('first day of next month'); 

$interval = DateInterval::createFromDateString('1 month'); 

$period = new DatePeriod($start, $interval, $end); 

foreach ($period as $dt) { 

echo $dt->format("Y-m") . "<br>\n"; 

} 
+0

Sir, was du gemacht hast, hat nur einen Datumsbereich, ich suche nach einem Vergleich zweier Datumsbereiche. –

+0

Wenn Sie Frage sehen, hat es zwei Datumsbereiche, Datumsbereich 1 und Datumsbereich 2. bedeutet insgesamt 4 Termine. 2 Startdaten und 2 Enddaten. –

1

Dies ist ein zweistufiger Prozess. Zuerst müssen Sie den engsten Datumsbereich anhand des Start- und Enddatums festlegen. Listen Sie dann die Monate zwischen diesen Daten auf.

// An array of start and end dates. There are just 2 in this example but you 
// could have as many as you like in the same "start, then end" format. 
$ranges = [ 
    [new DateTime('2014-07-01'), new DateTime('2015-06-30')], 
    [new DateTime('2012-02-01'), new DateTime('2014-12-31')] 
]; 

// Reduce the ranges to one set of two dates, the latest of the start dates 
// and the earliest of the end dates. 
$range = array_reduce($ranges, function($carry, $item){ 
    return $carry 
     ? [max($carry[0], $item[0]), min($carry[1], $item[1])] 
     : $item; 
}); 

var_dump($range); 
/* 
array (size=2) 
    0 => 
    object(DateTime)[1] 
     public 'date' => string '2014-07-01 00:00:00.000000' (length=26) 
     public 'timezone_type' => int 3 
     public 'timezone' => string 'Europe/London' (length=13) 
    1 => 
    object(DateTime)[4] 
     public 'date' => string '2014-12-31 00:00:00.000000' (length=26) 
     public 'timezone_type' => int 3 
     public 'timezone' => string 'Europe/London' (length=13) 
*/ 

// Shift both dates to the first of the month. Strictly speaking, we only 
// need to do this with the start date. 
$range = array_map(function($date){ 
    return $date->modify("first day of this month"); 
}, $range); 

var_dump($range); 
/* 
array (size=2) 
    0 => 
    object(DateTime)[1] 
     public 'date' => string '2014-07-01 00:00:00.000000' (length=26) 
     public 'timezone_type' => int 3 
     public 'timezone' => string 'Europe/London' (length=13) 
    1 => 
    object(DateTime)[4] 
     public 'date' => string '2014-12-01 00:00:00.000000' (length=26) 
     public 'timezone_type' => int 3 
     public 'timezone' => string 'Europe/London' (length=13) 
*/ 

$months = []; 
$interval = new DateInterval("P1M"); 
for ($month = $range[0]; $month <= $range[1]; $month->add($interval)) { 
    $months[] = $month->format("Y-m"); 
} 
var_dump($months); 
/* 
array (size=6) 
    0 => string '2014-07' (length=7) 
    1 => string '2014-08' (length=7) 
    2 => string '2014-09' (length=7) 
    3 => string '2014-10' (length=7) 
    4 => string '2014-11' (length=7) 
    5 => string '2014-12' (length=7) 
*/ 
Verwandte Themen