关于c#:确定两个时间范围是否重叠

Determine if two time ranges overlap

本问题已经有最佳答案,请猛点这里访问。

我正在用一个算法编写一个调度程序。在算法的最后一个阶段,我需要查看时间表(创建的时间表),看看学生当时是否已经被分配到某个班级。

因此,我们有:

1
2
Current Class Start Time: (2017, 02, 09, 10, 00, 00)
Current Class Finish Time: (2017, 02, 09, 11, 00, 00)

此时,我们将搜索时间表,查看学生A被分配到的其他班级:

例如,让我们假设他们已经被分配到同一个日期:

1
2
Class 'Z' Start Time: (2017, 02, 09, 09, 00, 00)
Class 'Z' Finish Time: (2017, 02, 09, 12, 00, 00)

现在我想找到类"z"的时间范围,并将其与当前类的时间范围进行比较。

2

有谁能帮我写下我的"if语句"以及如何解决这个问题吗?

按照我的想法,有三种可能性:

  • 如果"当前类"(开始和结束时间)落在"Z类"(冲突1)之间
  • 如果"当前类"的"开始时间"位于"Z类"(冲突2)之间
  • 如果"当前类"的"结束时间"位于"Z类"(冲突3)之间
  • 谢谢您


    这是最简单的方法:

    1
    2
    3
    4
    public static bool HasOverlap(DateTime start1, DateTime end1, DateTime start2, DateTime end2)
    {
        return start1 < end2 && end1 > start2;
    }

    或者,如果日期不一定是正确的开始/结束顺序:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public static bool HasOverlap(DateTime start1, DateTime end1, DateTime start2, DateTime end2)
    {
        return Min(start1, end1) < Max(start2, end2) && Max(start1, end1) > Min(start2, end2);
    }

    public static DateTime Max(DateTime d1, DateTime d2)
    {
        return d1 > d2 ? d1 : d2;
    }

    public static DateTime Min(DateTime d1, DateTime d2)
    {
        return d2 > d1 ? d1: d2;
    }

    注意,如果一个类以2结尾,下一个类以2开头,则不会有重叠。既然你在谈论课程,我想这就是你想要的。

    测试您的示例:

    2

    我为您添加了一些快速测试:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    public static void Test1()
    {
        // Class A overlaps class B
        DateTime aStart = DateTime.Parse("2017-01-01T09:00:00");
        DateTime aEnd = DateTime.Parse("2017-01-01T10:00:00");

        DateTime bStart = DateTime.Parse("2017-01-01T09:30:00");
        DateTime bEnd = DateTime.Parse("2017-01-01T11:00:00");

        bool isCorrect = HasOverlap(aStart, aEnd, bStart, bEnd) == true;
        Console.WriteLine($"1: {isCorrect}");
    }

    public static void Test2()
    {
        // Class A"surrounds" class B
        DateTime aStart = DateTime.Parse("2017-01-01T09:00:00");
        DateTime aEnd = DateTime.Parse("2017-01-01T15:00:00");

        DateTime bStart = DateTime.Parse("2017-01-01T09:30:00");
        DateTime bEnd = DateTime.Parse("2017-01-01T11:00:00");

        bool isCorrect = HasOverlap(aStart, aEnd, bStart, bEnd) == true;
        Console.WriteLine($"2: {isCorrect}");
    }

    public static void Test3()
    {
        // Class B"surrounds" class A
        DateTime aStart = DateTime.Parse("2017-01-01T09:30:00");
        DateTime aEnd = DateTime.Parse("2017-01-01T11:00:00");

        DateTime bStart = DateTime.Parse("2017-01-01T09:00:00");
        DateTime bEnd = DateTime.Parse("2017-01-01T15:00:00");

        bool isCorrect = HasOverlap(aStart, aEnd, bStart, bEnd) == true;
        Console.WriteLine($"3: {isCorrect}");
    }

    public static void Test4()
    {
        // Class A is before Class B
        DateTime aStart = DateTime.Parse("2017-01-01T09:00:00");
        DateTime aEnd = DateTime.Parse("2017-01-01T11:00:00");

        DateTime bStart = DateTime.Parse("2017-01-01T11:00:00");
        DateTime bEnd = DateTime.Parse("2017-01-01T12:00:00");

        bool isCorrect = HasOverlap(aStart, aEnd, bStart, bEnd) == false;
        Console.WriteLine($"4: {isCorrect}");
    }

    public static void Test5()
    {
        // Class A is after Class B
        DateTime aStart = DateTime.Parse("2017-01-01T12:00:00");
        DateTime aEnd = DateTime.Parse("2017-01-01T14:00:00");

        DateTime bStart = DateTime.Parse("2017-01-01T11:00:00");
        DateTime bEnd = DateTime.Parse("2017-01-01T12:00:00");

        bool isCorrect = HasOverlap(aStart, aEnd, bStart, bEnd) == false;
        Console.WriteLine($"5: {isCorrect}");
    }

    public static void Test6()
    {
        // Class B overlaps class A
        DateTime bStart = DateTime.Parse("2017-01-01T09:00:00");
        DateTime bEnd = DateTime.Parse("2017-01-01T10:00:00");

        DateTime aStart = DateTime.Parse("2017-01-01T09:30:00");
        DateTime aEnd = DateTime.Parse("2017-01-01T11:00:00");

        bool isCorrect = HasOverlap(aStart, aEnd, bStart, bEnd) == true;
        Console.WriteLine($"6: {isCorrect}");
    }

    static void Main()
    {
        Test1();
        Test2();
        Test3();
        Test4();
        Test5();
        Test6();
        Console.Read();
    }


    您需要再次检查:在这种情况下,Z级电流

    1
    2
    3
    4
    5
    DateTime startClassZ = new DateTime(2017, 02, 09, 09, 00, 00);
    DateTime endClassZ = new DateTime(2017, 02, 09, 12, 00, 00);

    DateTime startCurrent = new DateTime(2017, 02, 10, 10, 00, 00);
    DateTime endCurrent = new DateTime(2017, 02, 09, 11, 00, 00);

    和目前的Z级

    1
    2
    3
    4
    5
    DateTime startClassZ = new DateTime(2017, 02, 09, 09, 00, 00);
    DateTime endClassZ = new DateTime(2017, 02, 09, 12, 00, 00);

    DateTime startCurrent = new DateTime(2017, 02, 08, 10, 00, 00);
    DateTime endCurrent = new DateTime(2017, 02, 09, 13, 00, 00);

    完整代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    DateTime startClassZ = new DateTime(2017, 02, 09, 09, 00, 00);
    DateTime endClassZ = new DateTime(2017, 02, 09, 12, 00, 00);

    DateTime startCurrent = new DateTime(2017, 02, 08, 10, 00, 00);
    DateTime endCurrent = new DateTime(2017, 02, 09, 13, 00, 00);


    bool ClashCurrentStart = startClassZ < startCurrent && startCurrent < endClassZ;
    bool ClashCurrentEnd = startClassZ < endCurrent && endCurrent < endClassZ;
    //bool ClashCurrentBetween = ClashCurrentStart && ClashCurrentEnd;

    bool ClashClassZStart = startCurrent < startClassZ && startClassZ < endCurrent;
    bool ClashClassZEnd = startCurrent < endClassZ && endClassZ < endCurrent;
    //bool ClashClassZBetween = ClashClassZStart && ClashClassZEnd;


    bool Clash = ClashCurrentStart || ClashCurrentEnd || ClashClassZStart || ClashClassZEnd;

    if (!Clash)
    {
        //Assign
    }
    else // Clash
    {
        //Select Another Student
    }


    您提供三种可能性:

    a)整个currentClasszClass中。

    b)EDOCX1[0]的起始点在EDOCX1[1]中。

    c)currentClass端在zClass

    我想指出,a)的意思与b)和c)的意思相同,因此不需要特别注意。此外,如果你试图在你的头脑中(或在纸上)画一个最简单的课程持续时间草图,那么这些条件就会自然而然地出现:

    clash = (endOfCurrentClass > startOfZClass) || (startOfCurrentClass < endOfZClass)

    对于等价性(如endOfCurrentClass == startOfZClass)还有什么要考虑的,但这取决于其他约束条件(类时间是否包括类之间的停顿)?他们在同一个房间吗?……)然而,这是另一个问题。