3

I have a problem that seems quite hard to solve so I hope someone will have a good solution for me:)

I have a PHP program with a list of reservation for many conference rooms of an hotel. I need to calculate how much time during the day at least 1 conference room is in use.

Here is an exemple:

Room 1: 10h 00 to 13h 00  
Room 2: 11h 00 to 14h 00  
Room 3: 15h 00 to 16h 00  

With theses numbers, I need to calculate that the hotel is used during 5 hours (10h to 14h and 15h to 16h).

In the end, this tells me how many hours the hotel has to pay someone to check the rooms in case someone has a problem.

If you don't have a library that could help me, an algorithm could be a good start.

ajreal
  • 46,720
  • 11
  • 89
  • 119
MaxP
  • 325
  • 5
  • 10

2 Answers2

2

Algorithm outline:

  1. Order you intervals by starting time.
  2. Go through them and join neighbors that intersect. The intersection condition will be that the second interval's start time is before or equal to the first interval's end time. Because of the ordering only one loop will be needed.
  3. At this point you have only disjoint intervals and you can sum their spans to get the total span.

And here is an implementation of that algorithm:

<?php
// assuming hh:mm format for all the dates //
$intervals = array(
    array(
        'start' => '15:30',
        'end' => '16:00',
    ),
    array(
        'start' => '10:00',
        'end' => '13:00',
    ),
    array(
        'start' => '15:00',
        'end' => '16:09',
    ),
    array(
        'start' => '11:00',
        'end' => '14:00',
    ),
);

// 1. sort the intervals by start date //
function mySortIntervals($a, $b){
    return $a > $b;
}
usort($intervals, 'mySortIntervals');

// 2. merge adjoining intervals //
$active = 0;
$current = 1;
$length = count($intervals);
while($current < $length){
    if($intervals[ $current ]['start'] <= $intervals[ $active ]['end']){
        $intervals[ $active ]['end'] = max($intervals[ $active ]['end'], $intervals[ $current ]['end']);
        unset($intervals[ $current ]);
    }
    else{
        $active = $current;
    }
    $current++;
}

// 3. cout the total time //
$time = 0;
foreach($intervals as $interval){
    $time += strtotime($interval['end']) - strtotime($interval['start']);
}

// output //
echo str_pad((int) ($time/60/60), 2, '0', STR_PAD_LEFT).':';
echo str_pad((int) (($time/60)%60), 2, '0', STR_PAD_LEFT);
?>
Alin Purcaru
  • 43,655
  • 12
  • 77
  • 90
0

First of all, you need to define your interval or time span, for example every 15 minutes. Why this? because you need to control the gaps caused by room that finish before time, or for some other reason.

The time span can NOT be more than 15 minutes.(Time is money).

  1. Order a room (time span). It must check avaliable time span every time a request happen.
  2. Once the cell (time span) is checked that time span will not be available anymore.

To order a room just select the hour (00 til 23) and the quarter (00; 15; 30; 45;)

It worked to me quite well for an ISP business. I think is not different for a hotel. Because the idea of time span is the same.

But of course you can look for some class if you don't want to write your code at all.

devasia2112
  • 5,844
  • 6
  • 36
  • 56