为特定国家/地区计算没有假期的工作日

时间:2016-02-12 13:00:09

标签: c#

我一直在谷歌上搜索我的问题的解决方案,但到目前为止没有找到任何解决方案。 好吧,我发现了一些可以工作的parcial函数,但是因为我是C#的新手,我需要一些帮助合并所有代码才能工作。 所以,我需要计算2个日期之间的工作日,忽略周末和葡萄牙假期。 对于假期,我有这个代码返回所有葡萄牙假期:

public static List<DateTime> GetHolidays(int year)
    {
        List<DateTime> result = new List<DateTime>();

        result.Add(new DateTime(year, 1, 1)); //New Year Day
        result.Add(new DateTime(year, 4, 25)); //Dia da Liberdade (PT)
        result.Add(new DateTime(year, 5, 1)); //Labour Day
        result.Add(new DateTime(year, 6, 10)); //Dia de Portugal (PT)
        result.Add(new DateTime(year, 8, 15)); //Assumption of Mary
        result.Add(new DateTime(year, 10, 5)); //Implantação da república (PT)
        result.Add(new DateTime(year, 11, 1)); //All Saints' Day
        result.Add(new DateTime(year, 12, 1)); //Restauração da independência (PT)
        result.Add(new DateTime(year, 12, 8)); //Imaculada Conceição (PT?)
        result.Add(new DateTime(year, 12, 25)); //Christmas
        foreach (DateTime holiday in variable)
        {
            if (!result.Contains(holiday)) //if the holiday already exists then don't add
            {
                result.Add(holiday);
            }
        }
        return result;
    }

我计算工作日的功能是我在StackOverFlow中找到的那个:

public static int BusinessDaysUntil(this DateTime firstDay, DateTime lastDay, params DateTime[] bankHolidays)
    {
        firstDay = firstDay.Date;
        lastDay = lastDay.Date;
        if (firstDay > lastDay)
            throw new ArgumentException("Incorrect last day " + lastDay);

        TimeSpan span = lastDay - firstDay;
        int businessDays = span.Days + 1;
        int fullWeekCount = businessDays / 7;
        // find out if there are weekends during the time exceedng the full weeks
        if (businessDays > fullWeekCount * 7)
        {
            // we are here to find out if there is a 1-day or 2-days weekend
            // in the time interval remaining after subtracting the complete weeks
            int firstDayOfWeek = (int)firstDay.DayOfWeek;
            int lastDayOfWeek = (int)lastDay.DayOfWeek;
            if (lastDayOfWeek < firstDayOfWeek)
                lastDayOfWeek += 7;
            if (firstDayOfWeek <= 6)
            {
                if (lastDayOfWeek >= 7)// Both Saturday and Sunday are in the remaining time interval
                    businessDays -= 2;
                else if (lastDayOfWeek >= 6)// Only Saturday is in the remaining time interval
                    businessDays -= 1;
            }
            else if (firstDayOfWeek <= 7 && lastDayOfWeek >= 7)// Only Sunday is in the remaining time interval
                businessDays -= 1;
        }

        // subtract the weekends during the full weeks in the interval
        businessDays -= fullWeekCount + fullWeekCount;

        // subtract the number of bank holidays during the time interval
        foreach (DateTime bankHoliday in bankHolidays)
        {
            DateTime bh = bankHoliday.Date;
            if (firstDay <= bh && bh <= lastDay)
                --businessDays;
        }

        return businessDays;
    }

但是,此代码使用DateTime [] bankHolidays,我需要更改它以将我的假期考虑在内(GetHolidays())。 你能帮我改变一下代码吗? 感谢

2 个答案:

答案 0 :(得分:2)

据我所知,它是一个日期(例如5月1日),而不是年份,我们忽略(设置为1):

private static List<DateTime> PortugueseHolidays = new List<DateTime>() {
  new DateTime(1, 1, 1)), //New Year Day
  new DateTime(1, 4, 25), //Dia da Liberdade (PT)
  new DateTime(1, 5, 1), //Labour Day
  new DateTime(1, 6, 10), //Dia de Portugal (PT)
  new DateTime(1, 8, 15), //Assumption of Mary
  new DateTime(1, 10, 5), //Implantação da república (PT)
  new DateTime(1, 11, 1), //All Saints' Day
  new DateTime(1, 12, 1), //Restauração da independência (PT)
  new DateTime(1, 12, 8), //Imaculada Conceição (PT?)
  new DateTime(1, 12, 25), //Christmas
};

测试单个日期

private static Boolean IsHoliday(DateTime value, IEnumerable<DateTime> holidays = null) {
  if (null == holidays)
    holidays = PortugueseHolidays;

  return (value.DayOfWeek == DayOfWeek.Sunday) ||
         (value.DayOfWeek == DayOfWeek.Saturday) ||
          holidays.Any(holiday => holiday.Day == value.Day && 
                                  holiday.Month == value.Month);
}

对于范围(fromDate 包含toDate 已排除

public static int BusinessDaysUntil(this DateTime fromDate, 
                                    DateTime toDate,
                                    IEnumerable<DateTime> holidays = null) {
  int result = 0;

  for (DateTime date = fromDate.Date; date < toDate.Date; date = date.AddDays(1))
    if (!IsHoliday(date, holidays))
      result += 1;

  return result;
}

答案 1 :(得分:0)

您的目标是将@classmethod def new(cls, **props): '''Creates a new Thread instance, ensuring a unique _id.''' for i in range(5): try: thread = cls(**props) session(thread).flush(thread) return thread ...... continued 转换为List。将您的Array功能更改为:

GetHolidays

使用public static DateTime[] GetHolidays(int year) { List<DateTime> result = new List<DateTime>(); result.Add(new DateTime(year, 1, 1)); //New Year Day result.Add(new DateTime(year, 4, 25)); //Dia da Liberdade (PT) result.Add(new DateTime(year, 5, 1)); //Labour Day result.Add(new DateTime(year, 6, 10)); //Dia de Portugal (PT) result.Add(new DateTime(year, 8, 15)); //Assumption of Mary result.Add(new DateTime(year, 10, 5)); //Implantação da república (PT) result.Add(new DateTime(year, 11, 1)); //All Saints' Day result.Add(new DateTime(year, 12, 1)); //Restauração da independência (PT) result.Add(new DateTime(year, 12, 8)); //Imaculada Conceição (PT?) result.Add(new DateTime(year, 12, 25)); //Christmas foreach (DateTime holiday in variable) { if (!result.Contains(holiday)) //if the holiday already exists then don't add { result.Add(holiday); } } return result.ToArray<DateTime>(); } 作为最后一个参数调用BusinessDaysUntil函数。