Adam Kane
Adam Kane

Reputation: 43

How to detect overlapping start and end datetimes (C#, ASP.NET, MVC)

In a system we are designing, a requirement is to detect clashes when enrolling for new classes and are unsure what the best approach in detecting these clashes (or overlaps) is. Currently we have two lists, one holding class start times and the other holding class end times and are attempting to compare the both using a series of if statements. Our first problem is in how to compare two lists as the list items are stored as DateTimes and we are given errors in trying to compare the lists ("Operator '>= cannot be applied to operands of type 'bool' and 'bool' ").

In addition, we feel that the approach of using several if statements will prove very messy due to the number of possible combinations where overlaps could occur. Are there any more efficient ways to tackle this problem? We have checked a number of possible solutions (including the one below) but feel that it would involve writing to many if statements. Attached below is a segment of code showing our current attempt at detecting clashes.

        List<DateTime> startTimeList = new List<DateTime>();
        List<DateTime> endTimeList = new List<DateTime>();
        foreach (var module in moduleList)
        {
            foreach (var moduleClass in module.ModuleClass)
            {
                foreach (var day in typeof(DayOfWeek).GetEnumNames())
                {
                    // loop through days, instead of hardcoding "monday"
                    if (moduleClass.Day.ToString().Equals(day.ToString()))
                    {

                        //Trying to compare start and end times in this section
                        if (startTimeList.Contains(moduleClass.StartTime) >= endTimeList.Contains(moduleClass.EndTime))
                        {
                            System.Diagnostics.Debug.Write("<----------------------------------------- TIMETABLE CLASH ON MONDAY --------------------------------------------->");
                        }

                        else
                        {
                            startTimeList.Add(moduleClass.StartTime);
                            endTimeList.Add(moduleClass.EndTime);
                        }
                    }
                }
            }
        }

How check intersection of DateTime periods

Upvotes: 2

Views: 1818

Answers (1)

ediblecode
ediblecode

Reputation: 11971

There's a very simple line of code to detect whether a pair of DateTime objects overlap:

private bool IsOverlapping(ModuleClass currentClass, ModuleClass potentialClass)
{
    // Where Start & End are DateTime properties on ModuleClass.
    return potentialClass.Start < currentClass.End 
        && currentClass.Start < potentialClass.End;
}

If you need to compare these against every other possible class then you would need to compare each one against each other:

private bool IsOverlapping(List<ModuleClass> classes) 
{
    foreach(var currentClass in classes)
    {
        foreach(var potentialClass in classes.Where(x => x.Id != currentClass.Id))
        {
            // Clash has been found
            if (this.IsOverlapping(currentClass, potentialClass) return true;
        }
    }

    return false;
}

I'd like to point out that it would probably be more efficient to group the List<ModuleClass> into days so that it only compares classes on the same day of the week, and then if each list returns false when passed to IsOverlapping then you know there are no clashes, but you can extend this to implement it yourself.

Upvotes: 2

Related Questions