确定给定月份的第一个和最后一个工作日的最佳方法是什么

时间:2013-12-21 19:02:56

标签: c# datetime

确定某个月的第一个和最后一个工作日以及一组特定年度公众假期的最佳方法是什么?

假设

  • 营业日不是星期六,星期日或公众假期
  • 营业月开始于上述营业日,并在营业日结束。

这是一段准确说明我问题的代码:

struct BusinessMonthRange
{
    public DateTime startDate;
    public DateTime endDate;
} 

BusinessMonthRange GetBusinessMonthDateRange(int month, int year, List<DateTime> yearsPublicHolidays)
{
    //Calculate
    return BusinessMonthRange;
}

修改 为了提高清晰度,我在Lasse V. Karlsen和GraemeMiller的答案中指出了问题中的假设

2 个答案:

答案 0 :(得分:5)

这是一个简单的LINQPad程序,可以为您制定业务日期。

我将工作日定义为:

  • 不是星期六
  • 不是星期天
  • 假期列表中没有其中一个日期

请注意,这些规则可能会受到当地和文化差异的影响,世界上某些地方,周六将是营业日。

它的工作原理是从指定月份的第一天和最后一天开始,然后从两个方向向内工作,直到找到两端的工作日。换句话说,如果该月的最后一天不是营业日,那么让我们尝试前一天,依此类推,直到我们到达工作日为止。


假设:我假设“营业月”并不完全像“营业年”,因为“营业年”实际上可能跨越两个日历年的日期。

我的意思是,如果营业月份应该始终在星期一开始,并且有“如果日历月的第一周超过指定月份的一半,但是从上个月开始,那么营业月也从上一个日历月开始“。

例如,根据这样的规则,2013年10月的营业月份将从9月30日(即该周的周一)开始。我假设这不是你想要的商业月计算方式,因为如果你这样做,下面的代码就不会这样做。


无论如何,这是代码:

void Main()
{
    var holidays = new List<DateTime> { new DateTime(2013, 12, 31) };
    GetBusinessMonthDateRange(12, 2013, holidays).Dump();
}

struct BusinessMonthRange
{
    public DateTime startDate;
    public DateTime endDate;
}

BusinessMonthRange GetBusinessMonthDateRange(int month, int year,
    List<DateTime> yearsPublicHolidays)
{
    DateTime startDate = new DateTime(year, month, 1);
    DateTime endDate = new DateTime(year, month, 1).AddMonths(1).AddDays(-1);
    while (startDate.DayOfWeek == DayOfWeek.Saturday
           || startDate.DayOfWeek == DayOfWeek.Sunday
           || yearsPublicHolidays.Contains(startDate))
    {
        startDate = startDate.AddDays(1);
    }
    while (endDate.DayOfWeek == DayOfWeek.Saturday
           || endDate.DayOfWeek == DayOfWeek.Sunday
           || yearsPublicHolidays.Contains(endDate))
    {
        endDate = endDate.AddDays(-1);
    }

    return new BusinessMonthRange { startDate = startDate, endDate = endDate };
}

输出:

LINQPad output

说明:

  • 2013年12月1日是星期日,因此从12月2日开始。
  • 十二月三十一日是星期二,但我把这个日期列入2013年的公众假期清单,因此将其作为假期,因此选择了星期一30日作为结束。

答案 1 :(得分:1)

查看Itenso时间段库http://www.codeproject.com/Articles/168662/Time-Period-Library-for-NET

它具有解决此类问题的功能。什么是营业日。在英国,它将是Mon -Fri。其他地方例如中东有不同的日子。

Itenso会让你定义它们并找到它们。允许您使流程通用。

它是一个很棒的图书馆,我们经常使用它。所以,如果你有其他时间计算的东西值得探索