判断两个时间范围是否重叠

Determine if two time ranges overlap

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

因此,我们有:

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

此时我们将搜索时间表以查看其他 classes 学生 A 分配给了哪些学生:

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

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

现在我想找到Class'Z'的时间范围,并与CurrentClass的时间范围进行比较。

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, 09, 10, 00, 00);
DateTime StartCurrent = new DateTime(2017, 02, 09, 11, 00, 00);

if (They do not clash)
{
   Assign
}
if (Clash)
{
   Select Another Student
}

谁能帮我 'IF statements' 以及如何解决这个问题。

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

  1. 如果 'current class'(开始和结束时间)介于 'Class Z'(冲突 1)
  2. 之间
  3. 如果 'current class' 的 'start time' 落在 'Class Z' 之间(冲突 2)
  4. 如果 'current class' 的 'end time' 落在 'Class Z' 之间(冲突 3)

谢谢

这是最简单的方法:

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

或者如果日期不一定按正确的start/end顺序排列:

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;
}

请注意,如果一个 class 在 2 处结束,而下一个在 2 处开始,则不会有重叠。既然你在谈论 classes,我假设这就是你想要的。

正在测试您的示例:

static void Main(string[] args)
{
    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, 09, 10, 00, 00);
    DateTime EndCurrent = new DateTime(2017, 02, 09, 11, 00, 00);


    if(HasOverlap(startClassZ, endClassZ, StartCurrent, EndCurrent))
    {
        Console.WriteLine("clash");
    }
    else
    {
        Console.WriteLine("yay");
    }
    Console.Read();
}

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

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();
}

您提供了三种可能性:

A) 整个 currentClasszClass

B) currentClass 的开始在 zClass

C) currentClass 的结尾在 zClass

我想指出的是,A)与B)和C)的组合意义相同,因此不需要特别注意。此外,如果您尝试在脑海中(或纸上)画一个持续时间为 类 的最简单的草图,那么条件将很自然地弹出:

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

剩下的就是考虑等价性(例如 endOfCurrentClass == startOfZClass),但这取决于其他限制条件(class-times 是否包含 类 之间的停顿?他们在同一个房间吗? ...)。然而这是另一个问题。

您需要仔细检查: 在这种情况下具有电流的 classZ

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);

和当前的 classZ

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);

完整代码在这里:

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
}