Проверить, пересекает ли диапазон другой диапазон чисел

У меня 2 диапазона чисел:

  • $startTime to $endTime
  • $offerStartTime to $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, но подойдет псевдокод.


person Yahya Uddin    schedule 25.04.2017    source источник
comment
Вы имеете дело с отметками времени unix? в таком случае следует использовать класс DateTime   -  person Pedro Lobito    schedule 25.04.2017
comment
На самом деле это количество секунд в сутках. то есть от 0 до 86400   -  person Yahya Uddin    schedule 25.04.2017
comment
Запустите цикл в функции, которая принимает время начала, окончания, предложение начала, предложение, цикл от времени начала до конца, добавляя до начала ›= конец, и проверьте, находятся ли предложения начала / предложения в одном из циклов.   -  person clearshot66    schedule 25.04.2017
comment
Как 5 находится между 10 и 20? А 100?   -  person AbraCadaver    schedule 25.04.2017
comment
@AbraCadaver 5 - это offerStartTime, offerEndTime - это 11. Диапазон между обоими числами попадает в диапазон от 10 до 20, в частности 10 и 11.   -  person Pedro Lobito    schedule 25.04.2017
comment
@YahyaUddin Я думаю, что на основе ваших входов / ожидаемых выходов вы ищете пересечение диапазонов, но, на мой взгляд, попадает в диапазон, звучит так, как будто один диапазон должен полностью содержаться в другом (обе конечные точки). Вы можете уточнить?   -  person Don't Panic    schedule 25.04.2017
comment
Я думаю, что лучше было бы сформулировать пересечение диапазонов.   -  person Yahya Uddin    schedule 25.04.2017


Ответы (5)


Если вы просто проверяете, перекрывает ли какая-либо часть предложения какую-либо часть диапазона, это просто.

if ($offerStartTime < $endTime && $offerEndTime > $startTime)  {
    echo 'The ranges overlap';
}

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

введите здесь описание изображения

На основании ваших входных данных и ожидаемых ложных выходов я использовал < и >. Если вы хотите также включить диапазоны, которые пересекаются в точке, вам нужно вместо этого использовать <= и >=.

person Don't Panic    schedule 25.04.2017
comment
Знаешь, я думаю, ты прав. После всех этих сложных ответов, лол. Позвольте мне немного подождать, чтобы посмотреть, есть ли случаи, когда это не сработает, прежде чем проголосовать за это. - person Yahya Uddin; 25.04.2017
comment
Это работает для моих тестовых случаев (перекрытие, притирка и разделение вперед и назад) - person texdevelopers; 02.07.2021

Вам нужно проверить, больше ли начало вашего меньшего диапазона или равно его началу И если ваш конец меньшего диапазона меньше или равен концу вашего большего диапазона:

В этом случае 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;
}

?>
person Robert Wade    schedule 25.04.2017
comment
Ваш код, например, не будет работать с $outerRange = ['start' => 15, 'end' => 25];, поэтому это не решение - person user2455079; 16.05.2018

Надеюсь, это поможет вам, я пробовал это со всеми вашими входами, и он работает нормально ..

<?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";
        }
    }
}
person Sahil Gulati    schedule 25.04.2017

Вы можете использовать range и array_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 мы создаем 2 arrays, содержащие числа на основе переменных 4 (начало, конец), затем мы используем array_intersect, чтобы проверить, имеют ли два массива общие числа, если вывод не пуст, мы знаем, что числа (время) перекрываются.

person Pedro Lobito    schedule 25.04.2017

Через некоторое время я нашел эффективное простое решение, которое, кажется, работает (не стесняйтесь сказать мне, если это не так).

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

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

person Yahya Uddin    schedule 25.04.2017