Example #1
0
        /// <summary>
        /// Gets the time.
        /// </summary>
        /// <param name="date">The date.</param>
        /// <param name="calendar">The calendar.</param>
        /// <returns>System.Nullable{DateTime}.</returns>
        private static DateTime? GetTime(DateTime date, ICalendar calendar)
        {
            if (calendar == null || calendar.WorkingIntervals == null || !calendar.WorkingIntervals.Any())
            {
                return date;
            }

            var day = date.DayOfWeek;
            var skipInterval = false;

            foreach (var item in calendar.WorkingIntervals.OrderBy(x => x.StartDate).Where(x => x.Weekday == day.ToString()))
            {
                if (!item.StartDate.HasValue) continue;

                if (calendar.WorkingExceptions != null)
                {
                    var startDate = new DateTime(date.Year, date.Month, date.Day, item.StartDate.Value.Hour, item.StartDate.Value.Minute, 0);

                    var finishDateHour = 0;
                    var finishDateMinute = 0;
                    if (item.FinishDate != null)
                    {
                        finishDateHour = item.FinishDate.Value.Hour;
                        finishDateMinute = item.FinishDate.Value.Minute;
                    }
                    var finishDate = new DateTime(date.Date.Year, date.Date.Month, date.Date.Day, finishDateHour, finishDateMinute, 0);
                    var workingInterval = new DateTimeInterval(startDate, finishDate);
                    var intersectedExceptions = new List<DateTimeInterval>();

                    foreach (var exception in calendar.WorkingExceptions)
                    {
                        if (exception.StartDate.HasValue && exception.FinishDate.HasValue)
                        {
                            var compareResult = workingInterval.Compare(exception.StartDate.Value, exception.FinishDate.Value);
                            switch (compareResult)
                            {
                                case Interposition.Inside:
                                    skipInterval = true;
                                    break;
                                case Interposition.IntersectRight:
                                case Interposition.IntersectLeft:
                                case Interposition.Contains:
                                    intersectedExceptions.Add(new DateTimeInterval(exception.StartDate.Value, exception.FinishDate.Value));
                                    break;
                            }
                        }

                        if (skipInterval)
                            break;
                    }

                    if (intersectedExceptions.Count > 0)
                    {
                        for (var i = 0; i < intersectedExceptions.Count; i++)
                        {
                            //объеденить пересекающиеся между собой исключения
                            for (var j = i + 1; j < intersectedExceptions.Count; j++)
                            {
                                var uniteResult = intersectedExceptions[i].Unite(intersectedExceptions[j]);
                                if (uniteResult != null)
                                {
                                    //remove united items
                                    intersectedExceptions.Remove(intersectedExceptions[j]);
                                    intersectedExceptions.Remove(intersectedExceptions[i]);
                                    //insert united result instead
                                    intersectedExceptions.Insert(i, uniteResult);
                                }
                            }
                        }

                        // единственное исключение с которым осталось сравнить рабочее время.
                        var resultException = intersectedExceptions.OrderBy(exc => exc.StartDate).First();

                        switch (workingInterval.Compare(resultException))
                        {
                            case Interposition.Inside:
                                skipInterval = true;
                                break;
                            case Interposition.IntersectRight:
                                return resultException.FinishDate;
                            default:
                                return workingInterval.StartDate;
                        }
                    }
                }

                if (skipInterval == false)
                    return date.Date + item.StartDate.Value.TimeOfDay;

                skipInterval = false;
            }

            return null;
        }
Example #2
0
        private static ICalendarWorkingException GetWorkingException(DateTime date, ICalendar calendar, List<ICalendarWorkingInterval> workingIntervals, FrequencyPatternType pattern = FrequencyPatternType.Monthly)
        {
            if (calendar == null || !calendar.WorkingExceptions.Any() || workingIntervals == null || !workingIntervals.Any())
                return null;

            foreach (var item in workingIntervals)
            {
                if (!item.StartDate.HasValue) continue;

                var startDate = new DateTime(date.Year, date.Month, date.Day, item.StartDate.Value.Hour, item.StartDate.Value.Minute, 0);

                var finishDateHour = 0;
                var finishDateMinute = 0;
                if (item.FinishDate.HasValue)
                {
                    finishDateHour = item.FinishDate.Value.Hour;
                    finishDateMinute = item.FinishDate.Value.Minute;
                }
                var finishDate = new DateTime(date.Date.Year, date.Date.Month, date.Date.Day, finishDateHour, finishDateMinute, 0);
                var workingInterval = new DateTimeInterval(startDate, finishDate);

                foreach (var exception in calendar.WorkingExceptions.Where(x => x.StartDate.HasValue && x.FinishDate.HasValue && (x.FinishDate.Value > x.StartDate.Value)))
                {
                    var compareResult = workingInterval.Compare(exception.StartDate.Value, exception.FinishDate.Value);
                    switch (compareResult)
                    {
                        case Interposition.Inside:
                        case Interposition.IntersectRight:
                        case Interposition.IntersectLeft:
                            return pattern == FrequencyPatternType.Daily ? null : exception;
                        case Interposition.Contains:
                            return exception;
                    }
                }
            }

            return null;
        }