Here is a code for merging date-ranges in array.
The method gives new array, with the maximum mergining between the date-ranges,
meaning if there is a date-range that already exists with-in other, it can just skip,
so just if two or more dates can be combined into one big date-range - it will be made :)
.
-------------------------------Example #1:
array 0 => 's' => '2020-01-06' 'e' => '2020-01-10' 1 => 's' => '2020-01-07' 'e' => '2020-01-12' 2 => 's' => '2020-01-13' 'e' => '2020-01-16' 3 => 's' => '2020-01-22' 'e' => '2020-01-24' RESULT: array 0 => 's' => '2020-01-06' 'e' => '2020-01-16' 1 => 's' => '2020-01-22' 'e' => '2020-01-24'
-------------------------------Example #2:
array (size=8) 0 => 's' => '2020-01-01' 'e' => '2020-01-01' 1 => 's' => '2020-01-03' 'e' => '2020-01-03' 2 => 's' => '2020-01-09' 'e' => '2020-01-10' 3 => 's' => '2020-01-11' 'e' => '2020-01-22' 4 => 's' => '2020-01-14' 'e' => '2020-02-02' 5 => 's' => '2020-02-02' 'e' => '2020-02-03' 6 => 's' => '2020-02-04' 'e' => '2020-02-04' 7 => 's' => '2020-02-05' 'e' => '2020-02-07' RESULT: array (size=3) 0 => 's' => '2020-01-01' 'e' => '2020-01-01' 1 => 's' => '2020-01-03' 'e' => '2020-01-03' 2 => 's' => '2020-01-09' 'e' => '2020-02-07'
And here is the CODE:
$arrDateranges = array(
array('s' => '2020-01-22', 'e' => '2020-01-24'),
array('s' => '2020-01-06', 'e' => '2020-01-10'),
array('s' => '2020-01-07', 'e' => '2020-01-12'),
array('s' => '2020-01-13', 'e' => '2020-01-16'),
);
$arrMerged = mergeDateRanges($arrDateranges);
var_dump($arrDateranges);
var_dump($arrMerged);
//---------------------------------------------------------
// helper funciton to get NEXT date (or any modified date)
function getRelativeDate($p_sDate, $p_sModify, $p_sFormatIn = 'Y-m-d', $p_sFormatOut = 'Y-m-d') {
$oDT = DateTime::createFromFormat($p_sFormatIn, $p_sDate);
$oDT->modify($p_sModify);
return $oDT->format($p_sFormatOut);
}
function mergeDateRanges($p_arrDateranges) {
// sort by start date
usort($p_arrDateranges, function($a1, $a2) {
return $a1['s'] === $a2['s'] ? 0 : ($a1['s'] < $a2['s'] ? -1 : 1);
});
$arrMerged = array();
$arrLastDR = null;
foreach ($p_arrDateranges as $arrDR) {
if ($arrLastDR === null) {
$arrLastDR = $arrDR;
continue;
}
//
// NOTE: dateS is sorted thus $sDateS >= $arrLastDR['s']
//
if ($arrDR['e'] <= $arrLastDR['e']) {
continue; // already in the range.
}
// --- [e] > lastDR[e] ---
$sLastDateE_1 = getRelativeDate($arrLastDR['e'], '+1 day');
if ($arrDR['s'] <= $sLastDateE_1) { // lapping date-range until day+1
$arrLastDR['e'] = $arrDR['e'];
continue;
}
// there is gap, so need to create new date-range
array_push($arrMerged, $arrLastDR);
$arrLastDR = $arrDR;
}
if ($arrLastDR === null) {
array_push($arrMerged, $arrLastDR);
}
return $arrMerged;
}