Skip to content
Advertisement

Separate date to several intervals

I’ve got an array like the following :

$array1 = [
    [
      "start_datetime" => "2021-08-10 12:05:00"   ----> These are the initial intervals
      "end_datetime" => "2021-08-10 14:20:00"     ----> that I would like to separate
    ],
    [
      "start_datetime" => "2021-08-10 14:45:00"
      "end_datetime" => "2021-08-10 18:55:00"
    ],
    [
      "start_datetime" => "2021-08-10 19:25:00"
      "end_datetime" => "2021-08-10 21:00:00"
    ],
    ...
]

And another array :

$array2 = [
    [
      "start_datetime" => "2021-08-10 12:35:00"   ----> These are the intervals to 
      "end_datetime" => "2021-08-10 13:35:00"     ----> remove from the array
    ],
    ...
]

I would like to create a new $array3 that removes the intervals from $array2 in $array1 to give the following result :

$array3 = [
    [
      "start_datetime" => "2021-08-10 12:05:00"    ----> As you can see, these new array
      "end_datetime" => "2021-08-10 12:35:00"      ----> entries were added to remove
    ],
    [
      "start_datetime" => "2021-08-10 13:35:00"    ----> the interval in $array2 which
      "end_datetime" => "2021-08-10 14:20:00"      ----> are from 12:35 to 13:35
    ],
    [
      "start_datetime" => "2021-08-10 14:45:00"
      "end_datetime" => "2021-08-10 18:55:00"
    ],
    [
      "start_datetime" => "2021-08-10 19:25:00"
      "end_datetime" => "2021-08-10 21:00:00"
    ],
    ...
]

As you can see, in $array3 2 new entries were added to remove the interval used in $array2. I don’t know how can I tackle an algorithm to do this. Any help, advice or resources is appreciated.

Note that, in $array1 there will never be 2 same intervals, intervals are unique.

Advertisement

Answer

Here it is

function IndexOfPeriodToBrake($startRangeStr, $endRangeStr, $arr) {
  $start = strtotime($startRangeStr);
  $end = strtotime($endRangeStr);
  foreach($arr as $idx => $period) {
    $startP = strtotime($period['start_datetime']);
    $endP = strtotime($period['end_datetime']);
    if (($startP < $start)&&($endP > $end)) {
      return $idx;
    }
  }
  return false;
}

function checkOneRange(&$array, $startRangeStr, $endRangeStr) {
  $idxFound = IndexOfPeriodToBrake($startRangeStr, $endRangeStr, $array);
  if ($idxFound !== false) {
      $oldStartStr = $array[$idxFound]['start_datetime'];
      $oldEndStr = $array[$idxFound]['end_datetime'];
      $idx = -1;
      foreach ($array as $period) {
        $idx++;  
        if ($idx === $idxFound) {
          $array[$idx] = ['start_datetime' => $oldStartStr, 'end_datetime' => $startRangeStr];
          $idx++;
          $array[$idx] = ['start_datetime' => $endRangeStr, 'end_datetime' => $oldEndStr];
        } else {
          $array[$idx] = $period;
        }
      }
  }
    
}



$array3 = $array1;
foreach ($array2 as $range) {
  $startRangeStr = $range['start_datetime'];
  $endRangeStr = $range['end_datetime'];
  checkOneRange($array3, $startRangeStr, $endRangeStr);
}
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement