Exemplo n.º 1
0
        /// <summary>
        ///     Determines the number of business days between two dates
        /// </summary>
        /// <param name="start">The DateTime to use as the start when determining the difference</param>
        /// <param name="end">The DateTime to use as the end when determining the difference</param>
        /// <param name="weekendDays">
        ///     The days of the week to consider as the weekend. These days of the week will be excluded when
        ///     determining business days.
        /// </param>
        /// <param name="holidays">Holidays dates to exclude when determining business days</param>
        /// <returns>The number of business days between the <paramref name="start" /> and <paramref name="end" /> dates</returns>
        public static int BusinessDays(DateTime start, DateTime end, DayOfWeek[] weekendDays, params DateTime[] holidays)
        {
            start = start.Date;
            end = end.Date;

            if (start > end)
                throw new ArgumentException($"End date must be greater than {start:F}", nameof(end));

            if (weekendDays == null || !weekendDays.Any())
                throw new ArgumentException("Weekend Days is null or empty");

            var lastWeekendDay = weekendDays.Last();
            var span = end - start;
            var businessDays = span.Days + 1;
            var fullWeekCount = businessDays/7;

            if (businessDays > fullWeekCount*7)
            {
                var startDayOfWeek = start.DayOfWeek == lastWeekendDay
                                         ? 7
                                         : (int)start.DayOfWeek;
                var endDayOfWeek = end.DayOfWeek == lastWeekendDay
                                       ? 7
                                       : (int)end.DayOfWeek;

                if (endDayOfWeek < startDayOfWeek)
                    endDayOfWeek += 7;

                if (startDayOfWeek <= 6)
                {
                    if (endDayOfWeek >= 7)
                        businessDays -= 2;
                    else if (endDayOfWeek >= 6)
                        businessDays -= 1;
                }
                else if (startDayOfWeek <= 7 && endDayOfWeek >= 7)
                    businessDays -= 1;
            }

            businessDays -= (from holiday in holidays
                             where holiday.Date >= start && holiday.Date <= end && weekendDays.Any(weekendDay => weekendDay != holiday.DayOfWeek)
                             select holiday).Count() + 2*fullWeekCount;

            return businessDays;
        }