2015-10-17 99 views
1

我很難看看如何檢查多個*日期/時間值 - 範圍 - (意思是:開始結束時間)彼此衝突。如何檢查與多個日期時間衝突範圍

摘要&我需要使用的數據樣本。

我有一個(應用)事件表,用於創建一個表格,供用戶瀏覽和檢查(複選框)他們參加的所有會話/事件。

複選框的名稱是使用有關會話的信息生成的。 (與會話ID一起月/日開始/結束時間)

即:hours_9_5_p02_800_845

9 = month 
5 = date 
p02 = session id/event code 
800 = start time 
845 = end time 

全部由下劃線( 「_」)

如果用戶檢查分隔(並提交)多個會話,會有很多這些值來檢查時間衝突..

hours_9_5_p08_755_800 
hours_9_5_p02_800_845 
hours_9_5_p02_800_855 
hours_9_5_p03_800_845 
hours_9_5_p04_820_835 
hours_9_5_p04_845_900 
hours_9_5_REG_900_915 
hours_9_5_REG_1300_1305 
hours_9_5_REG_1310_1335 
hours_9_5_REG_1320_1335 

以上是字段列表/陣列的一個例子,我「可能」獲得的用戶選擇/提交我需要檢查是否有任何可能的衝突(顯然用戶不能同時在兩個地方):)上面有很多/幾個重疊的選擇相同的確切時間段。我可以開放給PHP,(在用戶提交後檢查)或javascript/jQuery(如果它可以做日期/時間RANGE衝突檢查,那麼可能更容易突出顯示那些行/元素頁面,如果在前端完成)

我最好的圖像,首先你需要分析這些複選框名稱/從字段列表字符串數組...

我已經像這樣做:(PHP)

function conflictParse($delimiter, $targetString){ 
    //echo 'fired'; 
    $breakDown = explode($delimiter, $targetString); 
    $startTime = substr_replace($breakDown[4] , ':', -2, 0); 
    $endTime = substr_replace($breakDown[5] , ':', -2, 0); 
    $startString = "$breakDown[1]/$breakDown[2]/2015 $startTime"; 
    $endString = "$breakDown[1]/$breakDown[2]/2015 $endTime"; 
    $startFormat = strtotime($startString); 
    $endFormat = strtotime($endString); 
    $start = date('m/d/Y G:i',$startFormat); 
    $end = date('m/d/Y G:i',$endFormat); 

    return "Session Times: $start -- $end <br>"; 
} 
echo conflictParse('_','hours_9_5_p02_800_845'); 

但我不清楚如何去使用這個RANGE的日期開始&結束時間檢查MULTIPLE其他日期開始/結束時間範圍

也許只是堅持PHP提交時解析/檢查衝突,然後返回一些(原始)名稱頁面數組到頁面(對於一些jQuery使用和突出顯示元素..等等(但我可以處理方面稍後..現在我需要幫助我如何可以得到上述解析'日期/時間'開始/結束範圍值檢查與其他'日期/時間'開始/結束範圍值衝突

更新:

這是當前的嵌套關聯數組我有工作比較:

Array ( 
    [0] => Array ( 
     [id] => hours_9_9_p02_800_845 
     [fullStart] => 09/09/2015 8:00 
     [fullEnd] => 09/09/2015 8:45 
     [month] => 9 
     [date] => 9 
     [session_code] => p02 
     [start] => 8:00 
     [end] => 8:45 
     [hasConflict] => false 
    ) 
    [1] => Array ( 
     [id] => hours_9_9_p02_800_855 
     [fullStart] => 09/09/2015 8:00 
     [fullEnd] => 09/09/2015 8:55 
     [month] => 9 
     [date] => 9 
     [session_code] => p02 
     [start] => 8:00 
     [end] => 8:55 
     [hasConflict] => false 
    ) 
    [2] => Array ( 
     [id] => hours_9_9_p03_800_845 
     [fullStart] => 09/09/2015 8:00 
     [fullEnd] => 09/09/2015 8:45 
     [month] => 9 
     [date] => 9 
     [session_code] => p03 
     [start] => 8:00 
     [end] => 8:45 
     [hasConflict] => false 
    ) 
    [3] => Array ( 
     [id] => hours_9_9_p04_820_830 
     [fullStart] => 09/09/2015 8:20 
     [fullEnd] => 09/09/2015 8:30 
     [month] => 9 
     [date] => 9 
     [session_code] => p04 
     [start] => 8:20 
     [end] => 8:30 
     [hasConflict] => false 
    ) 
    [4] => Array ( 
     [id] => hours_9_9_p04_845_900 
     [fullStart] => 09/09/2015 8:45 
     [fullEnd] => 09/09/2015 9:00 
     [month] => 9 
     [date] => 9 
     [session_code] => p04 
     [start] => 8:45 
     [end] => 9:00 
     [hasConflict] => false 
    ) 
    [5] => Array ( 
     [id] => hours_9_9_REG_1300_1315 
     [fullStart] => 09/09/2015 13:00 
     [fullEnd] => 09/09/2015 13:15 
     [month] => 9 
     [date] => 9 
     [session_code] => REG 
     [start] => 13:00 
     [end] => 13:15 
     [hasConflict] => false 
    ) 
    [6] => Array ( 
     [id] => hours_9_9_REG_1300_1330 
     [fullStart] => 09/09/2015 13:00 
     [fullEnd] => 09/09/2015 13:30 
     [month] => 9 
     [date] => 9 
     [session_code] => REG 
     [start] => 13:00 
     [end] => 13:30 
     [hasConflict] => false 
    ) 
) 

我需要將您的js函數轉換爲PHP,當然在我的時間使用fullStart/fullEnd變量比較我猜.. ??

(但你的功能仍然讓我感到困惑,因爲我看到了對事件1,事件2的引用..(以匹配你的例子)..

更新2:

以上是我的對象/數組(關聯數組),我從選擇一些複選框,並提交我的形式得到了...

這是我嘗試你的JS轉換代碼基於PHP [一些更新variablenames]:(和註釋掉線只是嘗試,並得到某種輸出的地方)

print_r($conflict_list); 

    function checkFirst($cf_presX, $cf_presY) { 
     //$cf_presX['fullStart'] < $cf_presY['fallStart'] ? checkConflict($cf_presX, $cf_presY) : checkConflict($cf_presY, $cf_presX); 

     echo 'Pres Check: '.$cf_presX[0] . '<br>'; 
     echo 'Pres Check: '.$cf_presY[0] . '<br>'; 
     /* 
     function checkConflict ($cc_presX, $cc_presY) {  
      if ($cc_presX.['fullEnd'] > $cc_presY.['fullStart']) { 
       $cc_presX.['hasConflict'] = true; 
       $cc_presY.['hasConflict'] = true; 
      } 
     } 
     */ 
    } 

    function setConflicts($events) { 
     for ($i = 0; $i < count($events); $i++) { 
      for ($j = 0; $i < count($events); $j++) { 
       // if it is not the same event 
       // if (i !== j) is the same $age['Peter'] 
       if ($events[$i]['id'] !== $events[$j]['id']) { 
       checkFirst($events[$i], $events[$j]); 
       } 
      } 
     } 
    } 
    setConflicts($conflict_list); 

我只是不斷得到未定義的循環偏移:(計數達100k +標記)

注意:未定義偏移量:0在 C:\瓦帕\ WWW \項目\雜項\ conflict_check_new.php上線49所介紹, 檢查:

注意:未定義偏移量:0在 C:\瓦帕\ WWW \項目\雜項\ conflict_check_new.php上線50所介紹, 檢查:

注意:未定義偏移量:0在 C:\瓦帕\ WWW \項目\雜項\ conflict_check_new.php上線49所介紹, 檢查:

+0

時間會按照您的示例進行排序嗎?還是隨機的? – jeff

+0

@jeff - 你指的這些 '時代': hours_9_5_p08_755_800 hours_9_5_p02_800_845 hours_9_5_p02_800_855 hours_9_5_p03_800_845 hours_9_5_p04_820_835 hours_9_5_p04_845_900 hours_9_5_REG_900_915 hours_9_5_REG_1300_1305 hours_9_5_REG_1310_1335 hours_9_5_REG_1320_1335 這些將是隨機的。(這些都是複選框名,因此提交的用戶選擇) 月份日期應該是相同的每個(如果改變了,不會有衝突)...但會話名稱,開始時間和結束時間(將採用24小時格式)可以是任何內容。 – whispers

+0

[確定是否兩個日期範圍重疊]可能的重複(http://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap) – CBroe

回答

1

同樣的邏輯也可以適用於PHP,但假設你可以得到你的活動進行到JavaScript和創建開始和結束日期對象的這樣一個數組:

var events = [ 
    { 
    id: 'event1', 
    start: new Date('1/1/1 5:00'), 
    end: new Date('1/1/1 6:00'), 
    hasConflict: false 
    }, 
    { 
    id: 'event2', 
    start: new Date('1/1/1 5:30'), 
    end: new Date('1/1/1 6:30'), 
    hasConflict: false 
    }, 
    { 
    id: 'event3', 
    start: new Date('1/1/1 7:30'), 
    end: new Date('1/1/1 8:30'), 
    hasConflict: false 
    } 
] 

您可以比較的事件,看看是否從第一個開始的結束時間是第二個開始時間的晚些時候。

function checkFirst (event1, event2) { 
    event1.start < event2.start 
    ? checkConflict(event1, event2) 
    : checkConflict(event2, event1) 

    function checkConflict (first, second) {  
    if (first.end > second.start) { 
     first.hasConflict = second.hasConflict = true 
    } 
    } 
} 

然後你可以檢查對方的事件。這裏的一個不是特別有效,但至少合適的環:

function flagAllEventsWithConflicts (events) { 
    events.forEach(event1 => { 
    events.forEach(event2 => { 
     event1.id !== event2.id && checkFirst(event1, event2) 
    }) 
    }) 
} 

更新:上述功能也可以被寫爲一個嵌套的for循環:

function flagAllEventsWithConflicts (events) { 
    for (var i = 0; i < events.length; i++) { 
    for (var j = 0; j < events.length; j++ { 
     // if it is not the same event 
     // if (i !== j) is the same 
     if (events[i].id !== events[j].id) { 
     checkFirst(events[i], events[j]) 
     } 
    } 
    } 
} 

然後檢查是否hasConflict是true或false:

flagAllEventsWithConflicts(events) 
console.table(events) 

Run this fiddle and checkout the console

+0

感謝您的答覆。所以對於使用示例..我需要一個forEach()來處理數組中的'each'事件/會話嗎?使用上面的示例,會有10個forEach()循環?然後? (我必須寫出來?)我發現需要查找第一個(最早的)開始時間/事件...以及需要檢查列表中的每個連續時間/事件。 – whispers

+0

但我認爲必須有更好的方法?提交後,我不知道用戶會選擇多少個「複選框」。該數組真的是未知的,直到提交和解析像我上面的嘗試,以獲得日期的東西分解。可能是你所建議的一個變體,用一個對象數組和一個索引計數器來動態循環遍歷forEach()? – whispers

+0

@whispers我不確定你的意思..你不必再寫任何比我提出的更多的代碼。您只需填充事件數組。你不會爲每個事件寫一個'forEach'循環,你只需將該數組傳遞給函數(我在編輯中更清晰) – azium

相關問題