我想出了一个额外的方法,可以用来获得最接近的前一个或当前的工作日,然后可以用来获得一个月的最后一个工作日 - 如果你正在调整周末假期,这也会考虑到:
public static DateTime LastBusinessDayInMonth(int year, int month, bool adjustForWeekend = true)
{
var lastDay = DateTime.DaysInMonth(year, month);
return PreviousOrCurrentBusinessDay(new DateTime(year, month, lastDay), adjustForWeekend);
}
public static DateTime PreviousOrCurrentBusinessDay(DateTime? beforeOrOnDate = null, bool adjustForWeekend = true)
{
var fromDate = beforeOrOnDate ?? DateTime.Today;
var year = fromDate.Year;
var month = fromDate.Month;
var day = fromDate.Day;
var holidays = UsHolidays(fromDate.Year, true).ToList(); // defined below
var dtCurrent = new DateTime(year, month, day);
while (!(dtCurrent.DayOfWeek < DayOfWeek.Saturday && dtCurrent.DayOfWeek > DayOfWeek.Sunday && !holidays.Contains(dtCurrent)))
{
dtCurrent = dtCurrent.AddDays(-1);
}
return dtCurrent;
}
我也在我的计算中使用了美国假期,我从下面的代码中看到了这一点:http://geekswithblogs.net/wpeck/archive/2011/12/27/us-holiday-list-in- c.aspx
这里可以看到代码:
public static IEnumerable UsHolidays(int year, bool adjustForWeekend)
{
return new List()
{
NewYears(year, adjustForWeekend),
MlkDay(year),
PresidentsDay(year),
GoodFriday(year),
MemorialDay(year),
IndependenceDay(year, adjustForWeekend),
LaborDay(year),
Thanksgiving(year),
Christmas(year, adjustForWeekend),
};
}
public static DateTime NewYears(int year, bool adjustForWeekend)
{
//NEW YEARS
return adjustForWeekend ? AdjustForWeekendHoliday(new DateTime(year, 1, 1).Date) : new DateTime(year, 1, 1).Date;
}
public static DateTime MemorialDay(int year)
{
//MEMORIAL DAY -- last monday in May
var memorialDay = new DateTime(year, 5, 31);
var dayOfWeek = memorialDay.DayOfWeek;
while (dayOfWeek != DayOfWeek.Monday)
{
memorialDay = memorialDay.AddDays(-1);
dayOfWeek = memorialDay.DayOfWeek;
}
return memorialDay.Date;
}
public static DateTime IndependenceDay(int year, bool adjustForWeekend)
{
//INDEPENCENCE DAY
return adjustForWeekend ? AdjustForWeekendHoliday(new DateTime(year, 7, 4).Date) : new DateTime(year, 7, 4).Date;
}
public static DateTime LaborDay(int year)
{
//LABOR DAY -- 1st Monday in September
var laborDay = new DateTime(year, 9, 1);
var dayOfWeek = laborDay.DayOfWeek;
while (dayOfWeek != DayOfWeek.Monday)
{
laborDay = laborDay.AddDays(1);
dayOfWeek = laborDay.DayOfWeek;
}
return laborDay.Date;
}
public static DateTime Thanksgiving(int year)
{
//THANKSGIVING DAY - 4th Thursday in November
var thanksgiving = (from day in Enumerable.Range(1, 30)
where new DateTime(year, 11, day).DayOfWeek == DayOfWeek.Thursday
select day).ElementAt(3);
var thanksgivingDay = new DateTime(year, 11, thanksgiving);
return thanksgivingDay.Date;
}
public static DateTime Christmas(int year, bool adjustForWeekend)
{
return adjustForWeekend ? AdjustForWeekendHoliday(new DateTime(year, 12, 25).Date) : new DateTime(year, 12, 25).Date;
}
public static DateTime MlkDay(int year)
{
//Martin Luther King Day -- third monday in January
var MLKDay = new DateTime(year, 1, 21);
var dayOfWeek = MLKDay.DayOfWeek;
while (dayOfWeek != DayOfWeek.Monday)
{
MLKDay = MLKDay.AddDays(-1);
dayOfWeek = MLKDay.DayOfWeek;
}
return MLKDay.Date;
}
public static DateTime PresidentsDay(int year)
{
//President's Day -- third monday in February
var presDay = new DateTime(year, 2, 21);
var dayOfWeek = presDay.DayOfWeek;
while (dayOfWeek != DayOfWeek.Monday)
{
presDay = presDay.AddDays(-1);
dayOfWeek = presDay.DayOfWeek;
}
return presDay.Date;
}
public static DateTime EasterSunday(int year)
{
var g = year % 19;
var c = year / 100;
var h = (c - c / 4 - (8 * c + 13) / 25 + 19 * g + 15) % 30;
var i = h - h / 28 * (1 - h / 28 * (29 / (h + 1)) * ((21 - g) / 11));
var day = i - ((year + year / 4 + i + 2 - c + c / 4) % 7) + 28;
var month = 3;
if (day > 31)
{
month++;
day -= 31;
}
return new DateTime(year, month, day);
}
public static DateTime GoodFriday(int year)
{
return EasterSunday(year).AddDays(-2);
}
public static DateTime AdjustForWeekendHoliday(DateTime holiday)
{
if (holiday.DayOfWeek == DayOfWeek.Saturday)
{
return holiday.AddDays(-1);
}
return holiday.DayOfWeek == DayOfWeek.Sunday ? holiday.AddDays(1) : holiday;
}