确定给定月份的第一个和最后一个工作日以及一组给定的年度公共(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 };
}
输出:
解释:
- 2013 年 12 月 1 日是星期日,因此从 12 月 2 日开始。
- 12 月 31 日是星期二,但我通过将该日期包含在 2013 年的公共(public)假期列表中使其成为假期,因此选择 30 日星期一作为结束。
关于c# - 确定给定月份的第一个和最后一个工作日的最佳方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20722464/