public class Interval
{
public DateTime DateStart { set; get; }
public DateTime DateEnd { set; get; }
/// <summary>
/// Проверяет если 2 интервала пересекаются
/// </summary>
/// <param name="p_firstInterval"></param>
/// <param name="p_secondInterval"></param>
/// <returns></returns>
public static bool IsIntersected(Interval p_firstInterval, Interval p_secondInterval)
{
bool result = false;
if (p_firstInterval != null && p_secondInterval != null)
{
result = p_firstInterval.DateStart < p_secondInterval.DateEnd && p_firstInterval.DateEnd > p_secondInterval.DateStart;
}
return result;
}
/// <summary>
/// Возвращает для 2х пересекающихся интервалов суммарный интервал
/// </summary>
/// <param name="p_firstInterval"></param>
/// <param name="p_secondInterval"></param>
/// <returns></returns>
public static Interval GetTotalInterval(Interval p_firstInterval, Interval p_secondInterval)
{
Interval result = null;
if (p_firstInterval != null && p_secondInterval != null)
{
if (IsIntersected(p_firstInterval, p_secondInterval))
{
DateTime startPoint = p_firstInterval.DateStart < p_secondInterval.DateStart ? p_firstInterval.DateStart : p_secondInterval.DateStart;
DateTime endPoint = p_firstInterval.DateEnd > p_secondInterval.DateEnd ? p_firstInterval.DateEnd : p_secondInterval.DateEnd;
result = new Interval() { DateStart = startPoint, DateEnd = endPoint };
}
}
return result;
}
/// <summary>
/// Возвращает в минутах суммарный интервал диапазонов дат в минутах
/// </summary>
public static double GetSharedInterval(List<Interval> p_intervals)
{
for (int i = 0; i < p_intervals.Count - 1; i++)
{
for (int j = i + 1; j < p_intervals.Count; j++)
{
if (Interval.IsIntersected(p_intervals.ElementAt(i), p_intervals.ElementAt(j)))
{
var newInterval = Interval.GetTotalInterval(p_intervals.ElementAt(i), p_intervals.ElementAt(j));
var newList = new List<Interval>(p_intervals);
newList.Remove(p_intervals.ElementAt(i));
newList.Remove(p_intervals.ElementAt(j));
newList.Add(newInterval);
return Interval.GetSharedInterval(newList);
}
}
}
return p_intervals.Sum(p => (p.DateEnd - p.DateStart).TotalMinutes);
}
/// <summary>
/// Возвращает в минутах пересечение 2х диапазонов дат
/// </summary>
/// <param name="p_dateStart1"></param>
/// <param name="p_dateEnd1"></param>
/// <param name="p_dateStart2"></param>
/// <param name="p_dateEnd2"></param>
/// <returns></returns>
public static double GetIntersectMinutes(DateTime p_dateStart1, DateTime p_dateEnd1, DateTime p_dateStart2, DateTime p_dateEnd2)
{
double minuteCount = 0;
if (p_dateStart1 >= p_dateStart2 && p_dateEnd1 <= p_dateEnd2)
{
minuteCount = (p_dateEnd1 - p_dateStart1).TotalMinutes;
}
else if (p_dateStart1 <= p_dateStart2 && p_dateEnd1 >= p_dateEnd2)
{
minuteCount = (p_dateEnd2 - p_dateStart2).TotalMinutes;
}
else if (p_dateStart1 >= p_dateStart2 && p_dateStart1 <= p_dateEnd2 && p_dateEnd1 >= p_dateEnd2)
{
minuteCount = (p_dateEnd2 - p_dateStart1).TotalMinutes;
}
else if (p_dateStart1 <= p_dateStart2 && p_dateEnd1 >= p_dateStart2 && p_dateEnd1 <= p_dateEnd2)
{
minuteCount = (p_dateEnd1 - p_dateStart2).TotalMinutes;
}
return minuteCount;
}
public override bool Equals(object obj)
{
return (obj is Interval && (obj as Interval).DateStart == this.DateStart && (obj as Interval).DateEnd == this.DateEnd);
}
}