Как добавить количество дней к дате, пропуская выходные и другие праздники - PullRequest
0 голосов
/ 28 декабря 2011

с учетом даты.Как я могу добавить к нему количество дней, пропуская выходные и другие праздничные дни между диапазонами?

List <DateTime> holidays = new List<DateTime>()
{
     new DateTime(2012, 01, 03),
     new DateTime(2012, 01, 26)
}; 

dateTimeReview.Value = CalculateFutureDate(dateTimeStart.Value, 7,holidays);

static DateTime CalculateFutureDate(DateTime fromDate, int numberofWorkDays, ICollection<DateTime> holidays)
{
     var futureDate = fromDate;

     for (var i = 0; i < numberofWorkDays; i++ )
     {
          if (futureDate.DayOfWeek == DayOfWeek.Saturday 
             || futureDate.DayOfWeek == DayOfWeek.Sunday
             || (holidays != null && holidays.Contains(futureDate)))
          {
              futureDate = futureDate.AddDays(1); // Increase FutureDate by one because of condition
              futureDate = futureDate.AddDays(1); // Add a working day
          }
     }
     return futureDate;
}

Ответы [ 4 ]

4 голосов
/ 28 декабря 2011

Чтобы пропустить праздники, сначала нужно создать собственный список праздников. Праздники в каждой стране разные, а также зависят от других факторов.

Затем следует добавлять дни один за другим в цикле с проверкой, если добавленный день не является выходным и не встречается в списке праздничных дней, пока не будет добавлено указанное количество дней.

К сожалению, нет более простого способа сделать это.

3 голосов
/ 17 июня 2013

Я попробовал код выше и не работал. Возвращенная дата будет как-то включать праздничные и выходные дни. Я также хочу проверить, чтобы возвращаемая дата была только в рабочие дни.

Итак, ниже мои модифицированные коды.

Как правило, он рассчитывает количество рабочих дней, которые будут добавлены, и, если дата окончания выпадает на праздничные / выходные дни, переносит дату на следующий день.

Обратите внимание, что предполагается, что дата начала не в выходные / праздничные дни.

static DateTime CalculateFutureDate(DateTime fromDate, int numberofWorkDays,   
                                    ICollection<DateTime> holidays)
{
     var futureDate = fromDate;
     for (var i = 0; i < numberofWorkDays; i++ )
     {
          if (futureDate.DayOfWeek == DayOfWeek.Saturday 
             || futureDate.DayOfWeek == DayOfWeek.Sunday
             || (holidays != null && holidays.Contains(futureDate)))
          {
              futureDate = futureDate.AddDays(1);
              numberofWorkDays++;
          }
          else
          {
              futureDate = futureDate.AddDays(1);
          }
     }
     while(futureDate.DayOfWeek == DayOfWeek.Saturday 
             || futureDate.DayOfWeek == DayOfWeek.Sunday
             || (holidays != null && holidays.Contains(futureDate)))
     {
          futureDate = futureDate.AddDays(1);
     }
     return futureDate;
}
0 голосов
/ 28 ноября 2015
public static DateTime AddBusinessDays(DateTime pActualDate, int pNumberofWorkDays)
        {
            ICollection<DateTime> holidays = GetAllHolidays();
            int i = default(int);
            while (i < pNumberofWorkDays)
            {
                pActualDate = pActualDate.AddDays(1);
                if (pActualDate.DayOfWeek == DayOfWeek.Saturday || pActualDate.DayOfWeek == DayOfWeek.Sunday
                    || (holidays != null && holidays.Contains(pActualDate))) { }
                else
                { i++; }
            }
            return pActualDate;
        }


private static ICollection<DateTime> GetAllHolidays()
        {
            ICollection<DateTime> holidays = GetPublicHolidays().Select(s => s.Holidays).ToList();
            HashSet<DateTime> finalHolidays = new HashSet<DateTime>();

            //if sunday holiday then the following monday will be holiday
            bool isMonday = GetCalendar().Any(s => s.Type == "KR" && s.IsMonday);

            foreach (var hol in holidays)
            {
                if (hol.DayOfWeek == DayOfWeek.Sunday && isMonday)
                {
                    //adding monday following day holiday to the list
                    finalHolidays.Add(hol.AddDays(1));
                }
            }
            //exclude weekends from the holiday list
            var excludeWeekends = holidays.Where(s => s.DayOfWeek == DayOfWeek.Sunday || s.DayOfWeek == DayOfWeek.Saturday);
            //adding monday to the existing holiday collection
            finalHolidays.UnionWith(holidays.Except(excludeWeekends));
            return finalHolidays;
        }
0 голосов
/ 28 декабря 2011

Я создал что-то похожее для проверки рабочего времени:

    public static DateTime AddBusinessHours(DateTime date, long hours)
    {
        int i = 0;

        DateTime tmpDate = date;

        do
        {
            tmpDate = tmpDate.AddHours(1);
            if (!IsWeekend(tmpDate) && !IsHoliday(tmpDate) && IsOfficeHours(tmpDate))
                i++;
        }
        while (i < hours);

        return tmpDate;
    }


    public static bool IsWeekend(DateTime date)
    {
        return (date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday);
    }


    public static bool IsHoliday(DateTime date)
    {
        //All dates in the holiday calendar are without hours and minutes.
        //With the normal date object, the Contains does not work.
        DateTime tmp = new DateTime(date.Year, date.Month, date.Day); 

        HolidayCalendar calendar = HolidayCalendar.Instance;

        return (calendar.Dates.Contains(tmp));
    }


    public static bool IsOfficeHours(DateTime date)
    {
        return (date.Hour >= 8 && date.Hour < 20);   //Office Hours are between 8AM and 8PM
    }

Но, как уже упоминалось выше, вам нужно запустить собственный календарь праздников.

...