C# overlapping time ranges

Date: 2017-02-16
public static TimeSpan DateRangeOverlapTimeSpan(DateTime min1, DateTime max1, DateTime min2, DateTime max2)
{
    if (min1 > max1 || min2 > max2)
    {
        throw new Exception("Invalid date range");
    }

    // Cases: 
    //            [---- Date1 ----]
    //                [--2C--]  
    //      [------------2D------------]   
    //      [----2A----]    [----2B----]
    // [--E--]                        [--F--]

    // 2E, 2F: skip
    if (max2 <= min1 || min2 >= max1)
    {
        return new TimeSpan(0);
    }

    // 2C
    if (min1 <= min2 && max1 >= max2)
    {
        return (max2 - min2).Duration();
    }
    // 2D
    if (min1 >= min2 && max1 <= max2) { return (max1 - min1).Duration(); } // 2A if (min1 >= min2 && max1 >= max2 && max2 >= min1)
    {
        return (max2 - min1).Duration();
    }
    // 2B
    if (min1 <= min2 && max1 >= min2 && max2 >= max1)
    {
        return (max1 - min2).Duration();
    }

    return new TimeSpan(0);
}

public static TimeSpan TimespanRangeOverlapTimeSpan(TimeSpan min1, TimeSpan max1, TimeSpan min2, TimeSpan max2)
{
    if (min1 > max1 || min2 > max2)
    {
        throw new Exception("Invalid date range");
    }

    // Cases: 
    //            [---- Date1 ----]
    //                [--2C--]  
    //      [------------2D------------]   
    //      [----2A----]    [----2B----]
    // [--E--]                        [--F--]

    // 2E, 2F: skip
    if (max2 <= min1 || min2 >= max1) {
        return new TimeSpan(0);
    }

    // 2C
    if (min1 <= min2 && max1 >= max2)
    {
        return (max2 - min2).Duration();
    }
    // 2D
    if (min1 >= min2 && max1 <= max2) { return (max1 - min1).Duration(); } // 2A if (min1 >= min2 && max1 >= max2 && max2 >= min1)
    {
        return (max2 - min1).Duration();
    }
    // 2B
    if (min1 <= min2 && max1 >= min2 && max2 >= max1)
    {
        return (max1 - min2).Duration();
    }            
    
    return new TimeSpan(0);
}

public void TestTimespanRangeOverlapTimeSpan()
{
    // Cases: 
    //            [---- Date1 ----]
    //                [--2C--]  
    //      [------------2D------------]   
    //      [----2A----]    [----2B----]
    // [--E--]                        [--F--]

    TimeSpan min1 = new TimeSpan(8, 0, 0);
    TimeSpan max1 = new TimeSpan(17, 0, 0);

    TimeSpan min2;
    TimeSpan max2;

    // Case C:
    min2 = new TimeSpan(10, 0, 0);
    max2 = new TimeSpan(11, 0, 0);
    Assert.AreEqual(DateTimeHelper.TimespanRangeOverlapTimeSpan(min1, max1, min2, max2), TimeSpan.FromHours(1));
    Assert.AreEqual(DateTimeHelper.TimespanRangeOverlapTimeSpan(min2, max2, min1, max1), TimeSpan.FromHours(1));

    // Case D:
    min2 = new TimeSpan(7, 0, 0);
    max2 = new TimeSpan(18, 0, 0);
    Assert.AreEqual(DateTimeHelper.TimespanRangeOverlapTimeSpan(min1, max1, min2, max2), TimeSpan.FromHours(9));
    Assert.AreEqual(DateTimeHelper.TimespanRangeOverlapTimeSpan(min2, max2, min1, max1), TimeSpan.FromHours(9));

    // Case A:
    min2 = new TimeSpan(7, 0, 0);
    max2 = new TimeSpan(10, 0, 0);
    Assert.AreEqual(DateTimeHelper.TimespanRangeOverlapTimeSpan(min1, max1, min2, max2), TimeSpan.FromHours(2));
    Assert.AreEqual(DateTimeHelper.TimespanRangeOverlapTimeSpan(min2, max2, min1, max1), TimeSpan.FromHours(2));

    // Case B:
    min2 = new TimeSpan(16, 0, 0);
    max2 = new TimeSpan(18, 0, 0);
    Assert.AreEqual(DateTimeHelper.TimespanRangeOverlapTimeSpan(min1, max1, min2, max2), TimeSpan.FromHours(1));
    Assert.AreEqual(DateTimeHelper.TimespanRangeOverlapTimeSpan(min2, max2, min1, max1), TimeSpan.FromHours(1));

    // Case E:
    min2 = new TimeSpan(4, 0, 0);
    max2 = new TimeSpan(8, 0, 0);
    Assert.AreEqual(DateTimeHelper.TimespanRangeOverlapTimeSpan(min1, max1, min2, max2), TimeSpan.FromHours(0));
    Assert.AreEqual(DateTimeHelper.TimespanRangeOverlapTimeSpan(min2, max2, min1, max1), TimeSpan.FromHours(0));

    // Case F:
    min2 = new TimeSpan(17, 0, 0);
    max2 = new TimeSpan(18, 0, 0);
    Assert.AreEqual(DateTimeHelper.TimespanRangeOverlapTimeSpan(min1, max1, min2, max2), TimeSpan.FromHours(0));
    Assert.AreEqual(DateTimeHelper.TimespanRangeOverlapTimeSpan(min2, max2, min1, max1), TimeSpan.FromHours(0));
}
6580cookie-checkC# overlapping time ranges