VitMosin
2/25/2015 - 1:00 PM

Interval.cs

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);
        }
    }