У меня есть 2 диапазона чисел:
$startTime
до $endTime
$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, но псевдокод был бы в порядке.
Если вы просто проверяете, перекрывает ли какая-либо часть предложения какую-либо часть диапазона, это просто.
if ($offerStartTime < $endTime && $offerEndTime > $startTime) { echo 'The ranges overlap'; }
Вот изображение, представляющее все возможности перекрытия и не перекрытия, чтобы визуализировать, почему это работает.
На основе ваших входов и ожидаемых ложных выходов я использовал <
и >
. Если вы хотите также включить диапазоны, которые пересекаются в точке, вам нужно будет использовать <=
и >=
вместо этого.
Вам нужно проверить, является ли начало вашего меньшего диапазона большим или равным началу вашего большего диапазона. И если ваш конец вашего меньшего диапазона меньше или равен концу вашего большего диапазона:
В этом случае 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; } ?>
Надеюсь, это поможет вам, я пробовал это со всеми вашими входами, и он отлично работает.
<?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"; } } }
промежуток<?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"; } } }
время<?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"; } } }
//$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; }
Вы можете использовать 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
чтобы проверить, имеют ли 2 массива общие числа, если выход не пуст, мы знаем, что числа (время) перекрываются.
Через некоторое время я нашел эффективное простое решение, которое, кажется, работает (не стесняйтесь сказать мне, если это не так).
($offerStartTime <= $startTime && $offerEndTime > $startTime) || ($offerStartTime > $startTime && $offerStartTime < $endTime)
Я также буду смотреть на ответы, которые лучше моих, поэтому, пожалуйста, пришлите мне свое решение.