Найти интервал дат в массиве с сериализованными датами в переполнении стека

Для системы управления отелем у меня есть следующее массив php в котором указаны даты бронирования гостиничного номера. Новые гости не могут быть забронированы в номер в эти даты.

Array([0] => '2017-02-23'
[1] => '2017-02-24'
[2] => '2017-04-01'
[3] => '2017-04-02'
[4] => '2017-04-03'
[5] => '2017-04-04'
[6] => '2017-04-05'
[7] => '2017-04-06'
[8] => '2017-04-07'
[9] => '2017-04-08'
[10] => '2017-04-09'
[11] => '2017-04-10'
[12] => '2017-04-11'
[13] => '2017-04-12'
[14] => '2017-04-13'
[15] => '2017-04-14'
[16] => '2017-04-15'
[17] => '2017-04-16'
[18] => '2017-04-17'
[19] => '2017-04-18'
[20] => '2017-04-19'
[21] => '2017-04-20'
[22] => '2017-04-21'
[23] => '2017-04-22'
[24] => '2017-04-23'
[25] => '2017-04-24'
[26] => '2017-04-25'
[27] => '2017-04-26'
[28] => '2017-04-27'
[29] => '2017-04-28'
[30] => '2017-04-29'
[31] => '2017-04-30'
)

Этот массив говорит нам, что в комнате зарезервировано 2 разных периода:

  1. 2017-02-23 в 2017-02-24
  2. 2017-04-01 в 2017-04-30

Я хотел бы найти диапазоны дат, в которых эта комната доступна, в определенном широком окне.

Например, если кто-то хотел остаться в комнате от 2017-02-15 в 2017-05-07, тогда я хотел бы, чтобы система возвращала следующие диапазоны дат для доступности:

  1. 2017-02-15 в 2017-02-22
  2. 2017-02-25 в 2017-03-31
  3. 2017-05-01 в 2017-05-07

Если кто-то хочет остаться в комнате от 2017-02-22 в 2017-03-30, тогда я хотел бы, чтобы система возвращала следующие диапазоны дат для доступности:

  1. 2017-02-25 в 2017-03-30

Любая помощь? Большое спасибо!!

2

Решение

Спасибо, Джордж, какая забавная маленькая проблема. Я прокатился моя собственная функция заполнения массива диапазона дат которым я очень горжусь. И с помощью нескольких функций массива и нескольких циклов foreach, я думаю, я удовлетворил краткое изложение. Здесь демонстрация.

Код:

function fillDateRange($a,$b,$x=0,$dates=[]){
while(end($dates)!=$b && $x=array_push($dates,date("Y-m-d",strtotime("$a +$x day"))));
return $dates;
}

$booked=array(0=>'2017-02-03',1=>'2017-02-24',2=>'2017-04-01',3=>'2017-04-02',
4=>'2017-04-03',5=>'2017-04-04',6=>'2017-04-05',7=>'2017-04-06',
8=>'2017-04-07',9=>'2017-04-08',10=>'2017-04-09',11=>'2017-04-10',
12=>'2017-04-11',13=>'2017-04-12',14=>'2017-04-13',15=>'2017-04-14',
16=>'2017-04-15',17=>'2017-04-16',18=>'2017-04-17',19=>'2017-04-18',
20=>'2017-04-19',21=>'2017-04-20',22=>'2017-04-21',23=>'2017-04-22',
24=>'2017-04-23',25=>'2017-04-24',26=>'2017-04-25',27=>'2017-04-26',
28=>'2017-04-27',29=>'2017-04-28',30=>'2017-04-29',31=>'2017-04-30');

$search=fillDateRange('2017-02-15','2017-05-07');  // pre-validated user input

// remove all dates from $search where exist in $booked...
$vacant=array_diff($search,$booked);

// group consecutive days
$date_checker=date("Y-m-d",strtotime("{$vacant[0]} -1 day"));
$x=0;
foreach($vacant as $date){
if($date!=date("Y-m-d",strtotime("$date_checker +1 day"))){++$x;}
$grouped[$x][]="$date";
$date_checker=$date;
}

echo "Array of vacant date ranges:";
foreach($grouped as $group){
$vacant_ranges[]=current($group)." to ".end($group);
}
echo "<pre>";
var_export($vacant_ranges);
echo "</pre>";

//echo "Array of arrays containing consecutive days:";
/*foreach($grouped as $group){
$vacant_arrays[current($group)." to ".end($group)]=$group;
}
echo "<pre>";
var_export($vacant_arrays);
echo "</pre>";*/

Выход:

Array of vacant date ranges:
array (
0 => '2017-02-15 to 2017-02-23',
1 => '2017-02-25 to 2017-03-31',
2 => '2017-05-01 to 2017-05-07',
)
0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector