php – Get time gap / free time from an array-ThrowExceptions

Exception or error:

Assume someone needs to to book a room. The room booking service is open from 08:00:00 to 18:00:00. So there is a limited reservation time:

array:2 [▼
  0 => "08:00:00"
  1 => "18:00:00"
]

And the room may also have some already booked times, it should be like this:

array:3 [▼
  0 => array:2 [▼
    0 => "08:05:00"
    1 => "09:00:00"
  ]
  1 => array:2 [▼
    0 => "10:00:00"
    1 => "15:00:00"
  ]
  2 => array:2 [▼
    0 => "16:00:00"
    1 => "17:00:00"
  ]
]

What I want to do is to find the time gaps, the result should be something like this:

array:4 [▼

  0 => array:2 [▼
    0 => "8:00:00"
    1 => "8:05:00"
  ]
  1 => array:2 [▼
    0 => "9:00:00"
    1 => "10:00:00"
  ]
  2 => array:2 [▼
    0 => "15:00:00"
    1 => "16:00:00"
  ]
  3 => array:2 [▼
    0 => "17:00:00"
    1 => "18:00:00"
  ]
]

It seems I have to sort the booked time array first, then complementing the array. But how to implement it in PHP code. Could someone help me solve this problem ? THX in advance.

How to solve:

If your bookings are not sorted by start time, you need to sort them. Then you can iterate over the bookings, creating free time entries between the end of one booking and the start of the next. Note that since your times are in HH:mm:ss format, you can compare them directly as strings; there is no need to convert them into an integer time value.

$hours = ["08:00:00", "18:00:00"];

$bookings = [["10:00:00", "15:00:00"],
             ["08:05:00", "09:00:00"],
             ["16:00:00", "17:00:00"]
             ];

$start = $hours[0];
$end = $hours[1];

// sort the bookings
$bstart = array_column($bookings, 0);
array_multisort($bstart, $bookings);

// get the free times
$time = $start;
$bindex = 0;
$free = array();
while ($time < $end && $bindex < count($bookings)) {
    if ($time < $bookings[$bindex][0]) {
        $free[] = [$time, $bookings[$bindex][0]];
    }
    $time = $bookings[$bindex][1];
    $bindex++;
}
// end of day free?
if ($time < $end) {
    $free[] = [$time, $end];
}
print_r($free);

Output:

Array
(
    [0] => Array
        (
            [0] => 08:00:00
            [1] => 08:05:00
        )
    [1] => Array
        (
            [0] => 09:00:00
            [1] => 10:00:00
        )
    [2] => Array
        (
            [0] => 15:00:00
            [1] => 16:00:00
        )
    [3] => Array
        (
            [0] => 17:00:00
            [1] => 18:00:00
        )
)

Demo on 3v4l.org

Leave a Reply

Your email address will not be published. Required fields are marked *