确定两个时间范围是否重叠

时间:2017-02-10 11:36:31

标签: c# .net winforms datetime timespan

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

因此,我们有:

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

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

例如,让我们说它们已被分配到同一天:

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

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

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”陈述'以及如何解决这个问题。

我正在考虑它的方式,有三种可能性:

  1. 如果'当前班级' (开始和结束时间)落在' Z类' (冲突1)
  2. 如果'开始时间'当前班级'落在Z'之间(冲突2)
  3. 如果'结束时间'当前班级'落在Z'之间(冲突3)
  4. 谢谢

3 个答案:

答案 0 :(得分:1)

这是最简单的方法:

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

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

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,那么将没有重叠。既然你在谈论课程,我假设这就是你想要的。

测试你的例子:

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

答案 1 :(得分:0)

您提供三种可能性:

A)整个currentClass位于zClass

B)currentClass的开头位于zClass

C)currentClass的结尾位于zClass

我想指出A)意味着与B)和C)相同,因此不需要特别注意。此外,如果你试图在课程的持续时间(或纸上)绘制一个最简单的草图,那么这些条件会很自然地突然出现:

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

剩下的就是考虑等价(例如endOfCurrentClass == startOfZClass)但这取决于其他约束(类时间是否在类之间包含暂停?它们是否在同一个房间?...)。然而,这是另一个问题。

答案 2 :(得分:0)

您需要仔细检查: 在这种情况下带有当前的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
}