如何在跳过周末和其他假期的同时将日期添加到日期

时间:2011-12-28 08:33:16

标签: c# datetime c#-4.0 date

给出日期。如何在跳过周末和其他假期之间添加一些天数?

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 个答案:

答案 0 :(得分:4)

要跳过假期,您首先需要创建自己的假期列表。每个国家的假期都不同,也受其他因素影响。

然后你应该在循环中逐个添加天数,检查添加的日期是否不是周末日,并且在节假日列表中没有出现,直到添加了给定的天数。

不幸的是,没有更简单的方法可以做到这一点。

答案 1 :(得分:3)

我尝试了上面的代码但没有用。返回的日期将以某种方式包括假期和周末。我还想检查返回的日期是否仅在工作日。

所以,下面是我修改后的代码。

基本上它会计算要添加的工作日数,如果结束日期是假日/周末,则将日期转移到第二天。

请注意,这是假设开始日期不是在周末/假日。

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

答案 2 :(得分:0)

我已经建立了类似于检查办公时间的东西:

    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
    }

但如上所述,您需要运行自己的假日日历。

答案 3 :(得分:0)

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