Verify if meeting datetime ranges overlap in an IEnumerable list of meetings I have an assignment where I need to find out if any of the meetings in a list of meeting class object have overlapping datetime ranges. What I have so far is this:

public class Meeting
{
    public DateTime Start { get; private set; }
    public DateTime End { get; private set; }

    public Meeting(DateTime start, DateTime end)
    {
        this.Start = start;
        this.End = end;
    }
}

public static class StaffMeetings
{
    public static bool DoesNotOverlap(IEnumerable&lt;Meeting&gt; meetings)
    {
        DateTime start = new DateTime();
        DateTime end = new DateTime();
        foreach (Meeting meeting in meetings)
        {
            if (start != DateTime.MinValue &amp;&amp; end != DateTime.MinValue)
            {
                if (start &lt; meeting.End &amp;&amp; end &gt; meeting.Start)
                {
                    return false;
                }
            }
            start = meeting.Start;
            end = meeting.End;
        }
        return true;
    }

    public static void Main(string[] args)
    {
        var format = System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat;

        Meeting[] meetings = new Meeting[]
        {
        new Meeting(DateTime.Parse("1/1/2015 20:00", format), DateTime.Parse("1/1/2015 21:30", format)),
        new Meeting(DateTime.Parse("1/1/2015 21:30", format), DateTime.Parse("1/1/2015 23:00", format)),
        new Meeting(DateTime.Parse("1/1/2015 23:10", format), DateTime.Parse("1/1/2015 23:30", format))
        };

        Console.WriteLine(StaffMeetings.DoesNotOverlap(meetings));
    }
}


Using the provided data set, I get the correct result but as I add more meetings, my results start to fail and performance drops.

I feel that the problem is in how I am iterating the list. However, if I sort the list first, I can most likely improve reliability but my performance would probably drop. I feel that there should be an algorithm for this, but so far, I have not had any luck finding one.
Sorting is what actually makes it work but if you also want it to be more linq-ish and more solid then you should change the following things:


move the overlap-logic into another method
change the method to return an IEnumerable&lt;Meeting[]&gt; for meetings that overlap 
use Any to find out whether any meeting overlap
make both methods extensions


Example:

public static IEnumerable&lt;Meeting[]&gt; Overlappings(this IEnumerable&lt;Meeting&gt; meetings)
{
    var last = (Meeting)null;
    foreach (var meeting in meetings.OrderBy(m =&gt; m.Start))
    {
        if (last != null &amp;&amp; meeting.OverlapsWith(last))
        {
            yield return new [] { last, meeting };
        }
        last = meeting;
    }
}

public static bool OverlapsWith(this Meeting x, Meeting y) 
{
    return x.Start &lt; y.Start ? x.End &gt; y.Start : y.End &gt; x.Start;
}


Gets overlapping meetings:

var overlappingMeetings = meetings.Overlappings();


or checks if there are any. It stops at the first overlapping pair found:

var meetingsOverlap = meetings.Overlappings().Any();


with these new extensions you are more flexible because you can easily check any two meetings overlap and it's easier to undestand than DoesNotOverlap. Usually it's better to write positive conditions and negate them if necessary rather than the other way around.



But even this could be further improved by overloading the two &lt; and &gt; operators:

public static bool operator &lt;(Meeting x, Meeting y) 
{
    return x.End &lt; y.Start;
}

public static bool operator &gt;(Meeting x, Meeting y)
{
    return x.End &gt; y.Start;
}


and making the OverlapsWith method still more natural:

public static bool OverlapsWith(this Meeting x, Meeting y) 
{
    return x.Start &lt; y.Start ? x &lt; y : y &gt; x;
}