测试一个范围是否与另一个数字范围相交

5
我有两个数字范围:
1. $startTime 到 $endTime 2. $offerStartTime 到 $offerEndTime 以上变量均为整数。
我想判断范围 $offerStartTime 到 $offerEndTime 是否在 $startTime 和 $endTime 的范围内。
例如,如果 $startTime 和 $endTime 范围是:10 到 20,则以下例子范围将返回 true:
- $offerStartTime: 5, $offerEndTime: 11 - $offerStartTime: 5, $offerEndTime: 100 - $offerStartTime: 10, $offerEndTime: 15 - $offerStartTime: 10, $offerEndTime: 100 - $offerStartTime: 12, $offerEndTime: 15 - $offerStartTime: 19, $offerEndTime: 100
以下将返回 false:
- $offerStartTime: 1, $offerEndTime: 3 - $offerStartTime: 90, $offerEndTime: 100 - $offerStartTime: 1, $offerEndTime: 10 - $offerStartTime: 20, $offerEndTime: 100
如何实现呢?最好提供 PHP 的解决方案,但伪代码也可以。

你正在处理Unix时间戳吗?如果是的话,你应该使用DateTime类。 - Pedro Lobito
1
实际上是一天中的秒数。即从0到86400。 - Yahya Uddin
1
数字5是如何介于数字1020之间的?那么,数字100呢? - AbraCadaver
1
@AbraCadaver,5offerStartTimeofferEndTime11。这两个数字之间的范围落在1020的范围内,具体为1011 - Pedro Lobito
我认为“范围交集”会更好一些。 - Yahya Uddin
显示剩余2条评论
6个回答

7
如果你只是想检查报价的任何部分是否与范围的任何部分重叠,那很简单。
if ($offerStartTime < $endTime && $offerEndTime > $startTime)  {
    echo 'The ranges overlap';
}

这里有一张图片,表示所有重叠和非重叠的可能性,以便说明为什么这个方法有效。enter image description here 根据您的输入和期望的错误输出,我使用了<>。如果您还想包括在一个点上相交的范围,那么您需要使用<=>=

你知道吗,我觉得你可能是对的。毕竟那些复杂的答案哈哈。在给这个点赞之前,让我再等一会儿看看是否有任何情况下这个方法不适用。 - Yahya Uddin
这对我的测试用例(重叠、不重叠和前后分离)都有效。 - texdevelopers

1
//$startTime to $endTime
//$offerStartTime to $offerEndTime
//you can compare php times by using normal comparators so this is just a logic problem. here's the solution.


//ok let's start by making sure that neither offered time is within the range because if it is we KNOW it's already good so

if(($offerStartTime < $endTime && offerStartTime > $startTime) || ($offerEndTime < $endTime && offerEndTime > $startTime)){
      return true;
 }
 //so it's not easily already within the range so we have to test if the lower one is under the starting one but the other is above. ie.
elseif(($offerStartTime < $startTime) && ($offerEndTime > $startTime)){
     return true; 
}
//so the only other acceptable possibility is that the offered start time is lower than the endtime and the offered end time is higher ie
elseif(($offerStartTime < $endTime) && ($offerEndTime > $endTime)){
      return true;
}
//so we've exhausted all other valid possibilities it must be false
else{
      return false;
}

1
您可以使用 rangearray_intersect,例如:

function time_intersect($startTime, $endTime, $offerStartTime, $offerEndTime)
{
    $start_to_end = range($startTime, $endTime, 1);
    $offer_start_end = range($offerStartTime, $offerEndTime, 1);
    if (!empty(array_intersect($start_to_end, $offer_start_end)))
    {
      # time overlaps
      return true;
    }
}

解释:

使用range创建基于4个变量(开始,结束)的数字数组,然后使用array_intersect检查这2个数组是否有公共数字,如果输出不为空,则知道数字(时间)重叠。


0

经过一段时间的研究,我找到了一个有效且简单的解决方案(如果不行,请随时告诉我)。

($offerStartTime <= $startTime && $offerEndTime > $startTime) ||
($offerStartTime > $startTime && $offerStartTime < $endTime)

我也会寻找比我的答案更好的解决方案,所以请仍然向我发送您的解决方案。


0
希望这对你有所帮助,我已经用你提供的所有输入尝试了一遍,而且运行良好。
<?php

ini_set('display_errors', 1);

$startTime=10;
$endTime=20;

$startOffset=100;
$endOffset=110;

$range=range($startTime,$endTime);//getting range of time

$offsetRange=range($startOffset,$endOffset);//getting range of offset


$set=array_intersect($range, $offsetRange);//getting the intersection

if(is_array($set) && count($set)>0);
{
    if(count($set)>1)
    {
        echo "Matched";
    }
    //added this to prevent this case offerStartTime: 1, offerEndTime: 10, 
    //ranges intersection is the endTime
    elseif(count($set)==1)
    {
        if($set[0]!=$startTime)
        {
            echo "Matched";
        }
    }
}

0

您需要测试较小范围的起始点是否大于或等于较大范围的起始点,并且较小范围的结束点是否小于或等于较大范围的结束点:

在这种情况下,10-20落在5-25之间,因此返回true。如果您不想包括范围的端点,只需将<=>=更改为分别为<>

<?php

$innerRange = ['start' => 10, 'end' => 20];
$outerRange = ['start' => 5, 'end' => 25];

echo isInRange($innerRange,$outerRange);

function isInRange($innerRange,$outerRange) {
    if ($innerRange['start'] >= $outerRange['start'] && $innerRange['end'] <= $outerRange['end'] ) {
         return true;   
    }
    return false;
}

?>

你的代码将无法与 $outerRange = ['start' => 15, 'end' => 25]; 一起使用,因此这不是一个解决方案。 - user2455079

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接