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

标签 c# datetime

确定给定月份的第一个和最后一个工作日以及一组给定的年度公共(public)假期的最佳方法是什么?

假设

  • 工作日是指不在星期六、星期日或特定公共(public)假期中的一天
  • 工作月开始于并结束于上述定义的工作日。

这里有一段代码可以准确说明我的问题:

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

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

编辑: 为了更加清晰,我在 Lasse V. Karlsen 和 GraemeMiller 在他们的回答中指出的问题中加入了假设

最佳答案

这是一个简单的 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 日开始。
  • 12 月 31 日是星期二,但我通过将该日期包含在 2013 年的公共(public)假期列表中使其成为假期,因此选择 30 日星期一作为结束。

关于c# - 确定给定月份的第一个和最后一个工作日的最佳方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20722464/

相关文章:

jquery - JQGrid 日期格式

python - 我如何根据日期时间对这个字典进行排序?

c# - 不使用类 System.Windows.Forms.Form 创建一个窗口?

c# - 在 C# 中为帐户(Active Directory、Gmail 等)构造类的最佳方式

c# - 错误 : "Spatial types and functions are not available for this provider"

delphi - 为什么当我调用 UnixToDateTime 时会得到数千年后的结果?

r - 填写data.table缺失日期的最快方法

php - 无法将日期和时间字段更新到 Mysql 记录中

c# - 在 .Set 之后直接在 EventWaitHandle 上调用 .Close (.Dispose) 是否安全?

c# - 为 BackgroundWorker 设计接口(interface)