using System.Collections.Generic;
public static void Main()
var from = DateTime.Parse("2017-06-15 08:00");
var to = from.AddHours(12);
var totalHours = (to - from).Days * 24;
List<DateTimRange> list1 = new List<DateTimRange>()
Start = DateTime.Parse("2017-06-15 08:00"),
End = DateTime.Parse("2017-06-15 10:00"),
Start = DateTime.Parse("2017-06-15 10:00"),
End = DateTime.Parse("2017-06-15 12:00"),
State = State.CanceladoEmpresaTransportista
Start = DateTime.Parse("2017-06-15 11:00"),
End = DateTime.Parse("2017-06-15 13:00"),
Start = DateTime.Parse("2017-06-15 14:00"),
End = DateTime.Parse("2017-06-15 16:00"),
State = State.NoDisponibilidad
Start = DateTime.Parse("2017-06-15 17:00"),
End = DateTime.Parse("2017-06-15 20:00"),
State = State.CanceladoUPM
Start = DateTime.Parse("2017-06-15 18:00"),
End = DateTime.Parse("2017-06-15 19:00"),
List<DateTimRange> list2 = new List<DateTimRange>()
Start = DateTime.Parse("2017-06-12 08:00"),
End = DateTime.Parse("2017-06-12 12:00"),
Start = DateTime.Parse("2017-06-12 12:00"),
End = DateTime.Parse("2017-06-12 16:00"),
State = State.CanceladoEmpresaTransportista
Start = DateTime.Parse("2017-06-12 13:00"),
End = DateTime.Parse("2017-06-12 16:00"),
Start = DateTime.Parse("2017-06-12 16:00"),
End = DateTime.Parse("2017-06-12 20:00"),
Start = DateTime.Parse("2017-06-13 04:00"),
End = DateTime.Parse("2017-06-13 08:00"),
Start = DateTime.Parse("2017-06-13 08:00"),
End = DateTime.Parse("2017-06-13 12:00"),
State = State.NoDisponibilidad
Start = DateTime.Parse("2017-06-13 12:00"),
End = DateTime.Parse("2017-06-13 16:00"),
List<DateTimRange> list3 = new List<DateTimRange>()
Start = DateTime.Parse("2017-06-12 08:00"),
End = DateTime.Parse("2017-06-12 12:00"),
State = State.CanceladoEmpresaTransportista
Start = DateTime.Parse("2017-06-12 09:00"),
End = DateTime.Parse("2017-06-12 11:00"),
State = State.CanceladoUPM
Start = DateTime.Parse("2017-06-12 09:00"),
End = DateTime.Parse("2017-06-12 10:00"),
Start = DateTime.Parse("2017-06-12 10:00"),
End = DateTime.Parse("2017-06-12 13:01"),
List<DateTimRange> list4 = new List<DateTimRange>()
Start = DateTime.Parse("2017-06-15 09:00"),
End = DateTime.Parse("2017-06-15 10:00"),
State = State.CanceladoEmpresaTransportista
Start = DateTime.Parse("2017-06-15 09:00"),
End = DateTime.Parse("2017-06-15 12:00"),
State = State.CanceladoUPM
List<DateTimRange> list5 = new List<DateTimRange>()
Start = DateTime.Parse("2017-06-15 07:00"),
End = DateTime.Parse("2017-06-15 10:10"),
Start = DateTime.Parse("2017-06-15 10:00"),
End = DateTime.Parse("2017-06-15 12:00"),
State = State.NoDisponibilidad
Start = DateTime.Parse("2017-06-15 14:00"),
End = DateTime.Parse("2017-06-15 17:00"),
State = State.CanceladoEmpresaTransportista
var ordered = list5.OrderBy(l => l.Start).ThenBy(e => e.End).ToList();
HashSet<DateTimRange> result = new HashSet<DateTimRange>();
var restList = new HashSet<DateTimRange>();
var current = ordered[0];
for (int i = 1; i < ordered.Count; i++)
var temp = new List<DateTimRange>()
temp = temp.OrderBy(t => t.Start).ThenBy(y => y.End).ToList();
if (current.End < next.Start)
var r2 = new DateTimRange
if (current.End == next.Start)
if (current.Start < next.Start)
var r1 = new DateTimRange
if (current.End < next.End)
else if (current.End > next.End)
var r1 = new DateTimRange
var resultOrderd = result.OrderBy(r => r.Start).ThenBy(e => e.End).Distinct().ToList();
foreach (var r in resultOrderd)
Console.WriteLine(string.Format("{0} -- {1} -- {2}", r.Start.ToString("HH:mm"), r.End.ToString("HH:mm"), r.State));
var start = resultOrderd.First().Start;
var end = resultOrderd.Last().End;
double total = (end - start).Hours * 60 + (end - start).Minutes;
int count = resultOrderd.Count;
for (int i = 0; i < count; i++)
if(t.State == State.CanceladoEmpresaTransportista || t.State == State.NoDisponibilidad)
incumplidas += (t.End - t.Start).Hours * 60 + (t.End - t.Start).Minutes;
if(t.State == State.Ocio)
var prev = resultOrderd[i - 1];
if (prev.State == State.CanceladoEmpresaTransportista || prev.State == State.NoDisponibilidad)
incumplidas += (t.End - t.Start).Hours * 60 + (t.End - t.Start).Minutes;
if (i + 1 < count && !added)
var next = resultOrderd[i + 1];
if (next.State == State.CanceladoEmpresaTransportista || next.State == State.NoDisponibilidad)
incumplidas += (t.End - t.Start).Hours * 60 + (t.End - t.Start).Minutes;
Console.WriteLine("-------------------------------------");
Console.WriteLine(string.Format("Total : {0} horas y {1} minutos", (int)total / 60, total % 60));
Console.WriteLine(string.Format("Incumplidas : {0} horas y {1} minutos", (int)incumplidas / 60, incumplidas % 60));
double cumplidas = total - incumplidas;
Console.WriteLine(string.Format("Cumplidas : {0} horas y {1} minutos", (int)cumplidas / 60, cumplidas % 60));
class DateTimRange : IComparable<DateTimRange>
public DateTime Start { get; set; }
public DateTime End { get; set; }
public State State { get; set; }
public int CompareTo(DateTimRange other)
else if (Start <= other.Start)
public override int GetHashCode()
return Start.GetHashCode();
public override bool Equals(object obj)
var other = obj as DateTimRange;
return Start == other.Start && End == other.End;
public override string ToString()
return string.Format("{0} -- {1} -- {2}", Start.ToString("HH:mm"), End.ToString("HH:mm"), State);
CanceladoEmpresaTransportista,