using System.Collections.Generic;
public static void Main()
TimeRange query = new TimeRange() { Start = new DateTime(2020, 1, 1, 0, 0, 0), End = new DateTime(2020, 1, 31, 23, 59, 59) };
List<TimeRange> exclusionRanges = new List<TimeRange>();
TimeRange er1 = new TimeRange() { Start = new DateTime(2019, 12, 28, 0, 0, 0), End = new DateTime(2020, 1, 6, 0, 0, 0) };
TimeRange er2 = new TimeRange() { Start = new DateTime(2020, 1, 12, 0, 0, 0), End = new DateTime(2020, 1, 16, 0, 0, 0) };
TimeRange er3 = new TimeRange() { Start = new DateTime(2020, 1, 28, 0, 0, 0), End = new DateTime(2020, 1, 29 , 0, 0, 0) };
exclusionRanges.Add(er1);
exclusionRanges.Add(er3);
exclusionRanges.Add(er2);
var ranges = query.excludeRanges(exclusionRanges);
foreach(var rv in ranges)
Console.WriteLine(rv.ToString());
public DateTime Start { get; set; }
public DateTime End { get; set; }
public TimeRange(DateTime start, DateTime end)
public IEnumerable<TimeRange> excludeRanges(IEnumerable<TimeRange> ranges)
var returnRanges = new List<TimeRange>();
var orderedRanges = ranges.OrderBy(r => r.Start);
if (!ranges.Any()) { return new List<TimeRange>() { this }; }
if (orderedRanges.First().Start <= Start && orderedRanges.First().End > Start) { min = orderedRanges.First().End; }
foreach (var tr in orderedRanges)
returnRanges.Add(new TimeRange(min, tr.Start));
if (returnRanges.Last().End < End)
returnRanges.Add(new TimeRange(orderedRanges.Last().End, End));
public override string ToString()
return $"{Start} - {End}";