如何确定在php范围内相交x次的日期?

时间:2019-02-22 00:30:48

标签: php

我们希望创建一个逗号分隔的日期列表,以告知我们预订的时间。有7个单位可租,所以我们想知道哪个日期存在> = 7

这个Stackoverflow thread很近,因为它可以确定交集,但是我正在寻找交集x次数的特定日期。

<?php 

// 2019-2-21 is present 8 times in the following array
$ranges = array(
        array('id' =>'59','start' => new DateTime('2019-02-19'), 'end' => new DateTime('2019-02-21')), 
        array('id' =>'58','start' => new DateTime('2019-02-19'), 'end' => new DateTime('2019-02-21')), 
        array('id' =>'55','start' => new DateTime('2019-02-19'), 'end' => new DateTime('2019-02-21')), 
        array('id' =>'57','start' => new DateTime('2019-02-19'), 'end' => new DateTime('2019-02-21')), 
        array('id' =>'108','start' => new DateTime('2019-02-21'), 'end' => new DateTime('2019-02-28')), 
        array('id' =>'109','start' => new DateTime('2019-02-19'), 'end' => new DateTime('2019-02-24')), 
        array('id' =>'110','start' => new DateTime('2019-02-21'), 'end' => new DateTime('2019-02-23')), 
        array('id' =>'111','start' => new DateTime('2019-02-21'), 'end' => new DateTime('2019-02-25')),  
        );

function intersects($lhs, $rhs) {
    return !($lhs['start'] > $rhs['end']  || $lhs['end'] < $rhs['start']);
}

function checkDates($ranges) {
    // Comparison loop 
    for($i = 0; $i < sizeof($ranges); $i++) {

        for($j = $i+1; $j < sizeof($ranges); $j++) {
            if(intersects($ranges[$i], $ranges[$j])) {
                echo "Date {$i} intersects with date {$j}<br>";
                }
            }
    }
}

    checkDates($ranges);
?>

当我们超出限制时,我能够在已知的特定日期进行识别

SELECT COUNT(*) FROM reservations 
WHERE reservations.`date` <= '$date' AND reservations.`dateLast` >= '$date'

这给了我们一个可以与数量单位进行比较的计数,但是我不确定如何创建一个与> = x相交的日期列表,这样我们就可以提前知道是否售罄。

更新以确认解决方案:

foreach ($ranges as $range) {
while ($range['start'] <= $range['end']) {
    $date = $range['start']->format('Y-m-d');
    $dates[$date] = (isset($dates[$date]) ? $dates[$date] : 0) + 1; 1;//define new $dates array
   $range['start']->modify('+1 day');
    }
}


 echo  $sold_out = array_filter($dates, function($n) { return $n >= 7; });



   echo '<pre>';
   print_r($range);
   echo '</pre>';

1 个答案:

答案 0 :(得分:1)

我认为您不需要相交范围。您只需要知道每个日期出现在范围列表中的次数,就可以迭代范围中的每个范围并计算日期。

foreach ($ranges as $range) {
    while ($range['start'] <= $range['end']) {
        $date = $range['start']->format('Y-m-d');
        $dates[$date] = ($dates[$date] ?? 0) + 1;
        // or $dates[$date] = (isset($dates[$date]) ? $dates[$date] : 0) + 1;
        $range['start']->modify('+1 day');
    }
}

/* Result:

array (size=10)
'2019-02-19' => int 5
'2019-02-20' => int 5
'2019-02-21' => int 8
'2019-02-22' => int 4 ...
*/

然后,您可以对其进行过滤以查找所有售罄的日期。

$sold_out = array_filter($dates, function($n) { return $n >= 7; });

我认为您也可以在SQL中执行此操作,方法是创建一个临时表,其中包含您感兴趣的日期范围内的所有日期,并将其加入到计数查询中。