2012-11-14 78 views
9

可能重複:
Determine Whether Two Date Ranges Overlap確定如果兩個時間段的任何一點重疊

我試圖找出如果兩個時間在PHP範圍重疊。我一直在提到Determine Whether Two Date Ranges Overlap作爲我的第一次嘗試,但是,它不符合所有情況。如果時間範圍嵌套在另一個時間範圍的開始時間和結束時間之間,則不會進行匹配。如果它與班次的開始或結束重疊,或者班次完全匹配,則按預期工作。

檢查什麼我談論的這個形象:

enter image description here

基本上,我試圖隱藏任何橙色的變化,如果他們在任何地方任何重疊的紅移。以下是我正在嘗試使用的代碼的相關部分。

if(($red['start'] <= $orange['end']) && ($red['end'] >= $orange['start'])) { 
    //Conflict handling 
} 

變量的值是UNIX時間戳。從邏輯上理解數字,我明白爲什麼上面的陳述失敗了。有很明顯的方法可以做更多的邏輯來確定一個轉變是否落在另一個轉變中(這是我可能需要做的),但是我希望獲得更普遍的結果。

編輯:添加每個塊的開始和結束時間的值。我同意我有應該工作。事實並非如此,我的問題在哪裏。我可能忽略了一些愚蠢的東西。

orange-start = 1352899800 
orange-end = 1352907000 

red-start = 1352923200 
red-end = 1352926200 

所以我的邏輯將陳述:

if((1352923200 <= 1352907000) && (1352926200 >= 1352899800)) 

所以緊接着,第一次比較失敗。

編輯2:它看起來像我的邏輯是健全的(我認爲是這樣),我的問題是與UNIX時間戳不匹配的實際時間顯示相關的東西。我感謝那些與我一起工作並幫助我發現問題的人。我希望我能接受安德烈和傑森的答案。

+0

在你的例子中,red.start *是*劣於orange.end並且red.end * *優於orange.start ... – alestanis

+0

+1,有興趣查看200+ upvotes的答案是否有* bug *。 –

+0

從來沒有說過它有一個錯誤,它的答案是正確的。我使用答案是問題。看下面的答案進一步鞏固,我現在正在嘗試他們。 –

回答

5

The logic是正確的。您提供的時間戳$red(8-8:50pm)和$orange(1:30-3:30pm)不重疊

得到正確的值(反映您的截圖),重疊確實發現:

function show_date($value, $key) { 
    echo $key, ': ', date('r', $value), PHP_EOL; 
} 

$red = array('start' => strtotime('today, 2pm'), 'end' => strtotime('today, 2:45pm')); 
$orange = array('start' => strtotime('today, 1:30pm'), 'end' => strtotime('today, 4pm')); 

array_walk($red, 'show_date'); 
array_walk($orange, 'show_date'); 

if (($red['start'] <= $orange['end']) && ($red['end'] >= $orange['start'])) { 
    echo 'Conflict handling'; 
} 

我的猜測是,你有一個時區轉換的問題。

+0

我開始認爲你是對的。我現在正在仔細研究時間戳,並且時間顯示正確,但UNIX時間戳不正確,因此看起來像移動不重疊,而它們確實是。 –

+0

你是如何進行時間戳轉換的? '的strtotime()'? –

+0

這個項目已經來自UNIX時間戳(來自日曆框架)。另一個項目來自日期時間對象,然後是「strtotime」。那裏有不一致的地方。我相信我可以追查下來。 –

1

您需要檢查您是否有「RED」任務,該任務在「橙色」任務的開始和結束之間開始或結束。像這樣,你應該檢測每個「橙色」任務與「紅色」任務重疊。

if((($red['start'] <= $orange['end']) && ($red['start'] >= $orange['start'])) || 
    (($red['end'] <= $orange['end']) && ($red['end'] >= $orange['start']))) { 
    //Conflict handling 
} 

編輯:由AndreyT說這是一種矯枉過正,如果你有兩個範圍,你可以用更少的檢查

+1

這太可悲了。最重要的是,如果您使用形式邏輯規則來簡化冗餘檢查,您將獲得OP在其版本中的確切內容 – AnT

+0

是的,您是對的,您的答案會更好地解釋並且完美地工作。不需要使用這個術語,並批評你自己的其他答案:) – koopajah

+1

額外的邏輯是不需要的。 –

0
if ((($red['start'] <= $orange['end']) && ($red['start'] >= $orange['start'])) 
    || (($red['end'] <= $orange['end']) && ($red['end'] >= $orange['start'])) 
    || (($red['start'] >= $orange['start']) && ($red['end'] >= $orange['end'])) 
    ) { 
// conflict happens if Red starts sometime between Orange start and end 
//    or if Red ends sometime between Orange start and end 
//    or if Red starts before Orange starts and ends after Orange ends 

} 
+1

額外的邏輯是不需要的。 –

7

做得更好[b1, e1][b2, e2](它已經建立了b1 < e1b2 < e2),則交疊由下面的邏輯表達式

not (e2 < b1 or e1 < b2) 

其可以是檢測改寫爲

e2 >= b1 and e1 >= b2 

在你的語法,這將是

if(($orange['end'] >= $red['start']) && ($red['end'] >= $orange['start'])) { 
    //Conflict handling 
} 

即你得到了正確的。你爲什麼要聲稱「通過邏輯來處理數字,我明白爲什麼上面的陳述失敗了。」我不清楚。究竟是什麼失敗? (我不知道爲什麼每個人都拿出可笑的「過度工程」檢查,並進行兩次以上的比較)。

當然,您必須決定觸摸範圍是否被視爲重疊並調整比較的嚴格性因此。

P.S.您在編輯中提供的樣本範圍不重疊,並且您的比較正確地將其識別爲無衝突情況。即一切都按原樣運作。你在哪裏看到這個問題?

相關問題