比较重叠的日期 - 不要避免

时间:2013-04-27 20:43:05

标签: vb.net linq datetime overlap

我正在编写一段时间表代码。我正在使用与这些模块相关的大学模块和事件系统,即

模块CSC3039 Event1 - 讲座 Event2 - 讲座 Event3 - Practial等

我需要检查模块中每个事件的时间,并比较冲突。冲突不需要纠正,只是突出显示。我将使用的表格Events包含Event_ID (PK), Module_code (FK), Start_Date_Time, End_Date_Time以及其他无关紧要的字段。我已经发现我需要实现一个For Each语句,最终产生一个if语句,例如:

if(startTime1< = endTime2或endTime1> = startTime2)CLASH

我的问题是试图在这里弄清楚实际的for循环。我不知道写什么来宣布我的开始时间和结束时间。我认为这是一个获取event1并获取其开始和结束然后检查事件2,3或4是否符合上述if语句的情况。我想要得到这个,但真的可以使用一些指导。

编辑...根据以下建议,我实施了以下代码:

    'return all relevant tables from the Modules database, based on the module code entered by the user.
    Dim eventTime = (From mods In db.Modules
                    Join evnt In db.Events On mods.Module_code Equals evnt.Module_code
                    Join rm In db.Rooms On rm.Room_ID Equals evnt.Room_ID
                    Join build In db.Buildings On build.Building_code Equals rm.Building_code
                    Where ((mods.Module_code = initialModCode) And (evnt.Room_ID = rm.Room_ID))
                    Select evnt.Event_ID, evnt.Module_code, evnt.Event_type, evnt.Start_Date_Time, evnt.End_Date_Time, build.Building_code, rm.Room_Number)


    'use the gridview to display the result returned by the above query
    gdvEventsTable.DataSource = eventTime
    gdvEventsTable.DataBind()

    Dim listClashes As New List(Of Array)

    For i As Integer = 0 To eventTime.Count - 1
        For j As Integer = i + 1 To eventTime.Count - 1
            If (eventTime.ToList(i).Start_Date_Time < eventTime.ToList(j).End_Date_Time) And (eventTime.ToList(i).End_Date_Time > eventTime.ToList(j).Start_Date_Time) Then
                MsgBox("Clash", MsgBoxStyle.MsgBoxSetForeground, "")
                listClashes.Add(eventTime)
            Else
                MsgBox("No Clash", MsgBoxStyle.MsgBoxSetForeground, "")
            End If
        Next
    Next

当我尝试将一个事件添加到我的数组列表时,我注意到,在调试中,没有事件被发送到列表。

3 个答案:

答案 0 :(得分:1)

如果要比较数组或某种集合中的所有事件对,可以使用如下循环:

    Dim ModuleEventArray() As ModuleEvent
    '...
    For i As Integer = 0 To ModuleEventArray.Length - 1
        For j As Integer = i + 1 To ModuleEventArray.Length - 1
            'test if ModuleEventArray(i) overlaps with ModuleEventArray(j)
        Next
    Next

这里的ModuleEvent将是另一个具有字段startTime和endTime的类或结构。测试

if (startTime1 <= endTime2 or endTime1 >= startTime2)

不足以测试重叠,但也许你可以自己找出正确的测试:)


编辑: 因为我看到你使用某种集合而不是数组,所以你需要的代码应该是:

For i As Integer = 0 To eventTime.Count - 1
    For j As Integer = i + 1 To eventTime.Count - 1
        If (eventTime.Item(i).Start_Date_Time < eventTime.Item(j).End_Date_Time) And (eventTime.Item(i).End_Date_Time > eventTime.Item(j).Start_Date_Time) Then
            MsgBox("Clash")
        Else
            MsgBox("No Clash")
        End If
    Next
Next

答案 1 :(得分:0)

在编写代码之前,首先需要确定算法的内容。例如,如果你使用你想象的天真方法,那么代码确实很简单(基本上是2个嵌套循环)但是复杂性如果是O(n²)。

取决于您拥有的数据量,是否在数据库中,您预计冲突的可能性,您是否始终拥有完整的事件列表,或者您需要逐步找到冲突等等...不同的解决方案可能是首选一个考虑因素是你是否需要将列表分成非冲突的事件集,或者只是产生一个是/否答案(每个事件一个),说明是否存在冲突。

您可能会考虑做一些不同的事情,比如在开始比较之前按开始时间对列表进行排序。这将允许您只走一次列表。

答案 2 :(得分:0)

我的比较来自数据库。在下面的代码之前,我有一个查询,它根据Events的用户输入返回Module_Code表中的所有记录。此代码将通过msgbox显示冲突。我将更改它以填充列表。它不是最漂亮的,可能会导致很多重复,但它实现了我的主要目标。

For Each evnt In eventTime


        Dim startTime1 = evnt.Start_Date_Time

        Dim endTime1 = evnt.End_Date_Time

        For Each evat In eventTime
            Dim startTime2 = evat.Start_Date_Time


            Dim endTime2 = evat.End_Date_Time



            If (startTime1 < endTime2) And (endTime1 > startTime2) Then
                MsgBox("Clash")
            Else
                MsgBox("No Clash")
            End If

        Next

    Next