2017-02-24 1 views
0

Ich habe folgendes Array mit Daten in php:kontinuierliche Zeiträume Finden von serialisierten Daten in PHP

Array ( 
    [0] => '2017-02-22' 
    [1] => '2017-02-23' 
    [2] => '2017-04-03' 
    [3] => '2017-04-04' 
    [4] => '2017-04-05' 
    [5] => '2017-04-06' 
) 

Gibt es eine Möglichkeit das kontinuierliche Datum Perioden innerhalb des Arrays enthalten zu finden?

beispielsweise für die obige Anordnung würde das erwartete Ergebnis sein:

2017-02-22 bis 2017-02-23

und

2017-04-03 zu 2017-04- 06.

Danke für Ihre Hilfe!

+1

Wiederholen Sie die Eingaben und prüfen Sie, ob der vorherige Eintrag einen Tag vor dem aktuellen Eintrag war. (Wahrscheinlich möchten Sie DateTime-Objekte aus diesen Datenstrings erstellen, um dies einfacher überprüfen zu können.) Wenn ja, haben Sie immer noch eine zusammenhängende Periode, wenn Sie nicht am Anfang einer neuen sind. – CBroe

+0

Vielleicht interessant (Duplikat)? : [Algorithmus zum Kombinieren/Zusammenführen von Datumsbereichen] (http://stackoverflow.com/questions/4972552/algorithm-to-combine-merge-date-range) –

Antwort

1

Es gibt viele Möglichkeiten, diese Aufgabe auszuführen. Einige, die schwerer zu lesen sind als andere. Ich werde ein paar aufzählen. Ich empfehle die Verwendung der ersten Methode für Effizienz und vielleicht die dritte Methode für eine einfache Änderung der Ausgabe.

Ich habe die Beispieldaten im Array $dates geändert, um zu zeigen, dass es Monatsänderungen und Stand-Alone-Daten berücksichtigt.

Alle folgenden Methoden gehen davon aus, dass die Daten bereits in aufsteigender Reihenfolge sortiert sind. Wenn nicht, dann funktioniert sort() an Y-m-d formatierten Daten; ansonsten wird usort() benötigt.

Meine Methoden werden eine Reihe von Daten wie diese nehmen:

$dates=[ 
    '2017-02-28', 
    '2017-03-01', 
    '2017-04-03', 
    '2017-04-04', 
    '2017-04-06', 
    '2017-04-08', 
    '2017-04-09', 
    '2017-04-10' 
]; 

Und Ausgang dieses:

array (
    0 => '2017-02-28 to 2017-03-01', 
    1 => '2017-04-03 to 2017-04-04', 
    2 => '2017-04-06 to 2017-04-06', 
    3 => '2017-04-08 to 2017-04-10', 
) 

Methode # 1: Einzel Foreach-Schleifen (Demo)

foreach($dates as $date){ 
    if(!isset($start_date)){ 
     $start_date=$date; // temporarily store new start date 
    }elseif($date==date("Y-m-d",strtotime("$start_date +1 day")) || (isset($end_date) && $date==date("Y-m-d",strtotime("$end_date +1 day")))){ 
     $end_date=$date; // temporarily store new or overwrite existing end date 
    }else{ 
     $result[]="$start_date to ".(!isset($end_date)?$start_date:$end_date); // current date is not in group, move temporary dates to result array 
     $start_date=$date; // overwrite previous start date 
     unset($end_date); // destroy previous end date 
    } 
} 
$result[]="$start_date to ".(!isset($end_date)?$start_date:$end_date); // move temporary dates to result array 
var_export($result); 

Methode # 2: Geschachtelt während Schleifen (Demo)

$copy=$dates; // make a copy in case $dates is to be used again later 
while($copy){ // iterate until the array is empty 
    while(!isset($range) || current($copy)==date("Y-m-d",strtotime(substr($range,-10)." +1 day"))){ // iterate while date is new or consecutive 
     $range=(!isset($range)?'':substr($range,0,10).' to ').array_shift($copy); // temporarily store/overwrite the range data 
    } 
    $result[]=(strlen($range)==10?"$range to $range":$range); // permanently store range data 
    unset($range); // destroy range string, for next iteration 
} 
var_export($result); 

Methode # 3: Zwei Foreach Loops (Demo)

foreach($dates as $date){ 
    if(!isset($grouped)){ // first group 
     $i=0; // first group, index is zero 
    }elseif($date!=date("Y-m-d",strtotime("$date_checker +1 day"))){ // if non-consecutive 
     ++$i; // next group, index is incremented 
    } 
    $grouped[$i][]=$date_checker=$date; // store date as temporary date checker and into appropriate group 
} 

foreach($grouped as $group){ 
    $result[]=current($group)." to ".end($group); 
} 
var_export($result); 

Oder von dem $grouped Array in Methode 3, könnten Sie einfach die Ausgabestruktur ändern "Bereich Strings" als Schlüssel mit Sub-Arrays hält enthalten die einzelnen Termine als Elemente mit dieser:

foreach($grouped as $group){ 
    $result[current($group)." to ".end($group)]=$group; 
} 

Alternative Ausgang:

array (
    '2017-02-28 to 2017-03-01' => 
    array (
    0 => '2017-02-28', 
    1 => '2017-03-01', 
), 
    '2017-04-03 to 2017-04-04' => 
    array (
    0 => '2017-04-03', 
    1 => '2017-04-04', 
), 
    '2017-04-06 to 2017-04-06' => 
    array (
    0 => '2017-04-06', 
), 
    '2017-04-08 to 2017-04-10' => 
    array (
    0 => '2017-04-08', 
    1 => '2017-04-09', 
    2 => '2017-04-10', 
), 
) 
Verwandte Themen