如何计算.NET中该月的最后一个工作日?
答案 0 :(得分:14)
假设营业日是星期一至星期五(这不考虑假期),此功能应返回正确的答案:
Function GetLastBusinessDay(ByVal Year As Integer, ByVal Month As Integer) As DateTime
Dim LastOfMonth As DateTime
Dim LastBusinessDay As DateTime
LastOfMonth = New DateTime(Year, Month, DateTime.DaysInMonth(Year, Month))
If LastOfMonth.DayOfWeek = DayOfWeek.Sunday Then
LastBusinessDay = LastOfMonth.AddDays(-2)
ElseIf LastOfMonth.DayOfWeek = DayOfWeek.Saturday Then
LastBusinessDay = LastOfMonth.AddDays(-1)
Else
LastBusinessDay = LastOfMonth
End If
Return LastBusinessDay
End Function
答案 1 :(得分:10)
我会在星期一到星期五的工作周这样做:
var holidays = new List<DateTime>{/* list of observed holidays */};
DateTime lastBusinessDay = new DateTime();
var i = DateTime.DaysInMonth(year, month);
while (i > 0)
{
var dtCurrent = new DateTime(year, month, i);
if(dtCurrent.DayOfWeek < DayOfWeek.Saturday && dtCurrent.DayOfWeek > DayOfWeek.Sunday &&
!holidays.Contains(dtCurrent))
{
lastBusinessDay = dtCurrent;
i = 0;
}
else
{
i = i - 1;
}
}
答案 2 :(得分:6)
首先,获取该月的最后一天。然后继续递减,直到你要么超过月初,要么达到验证为“营业日”的日期。
答案 3 :(得分:6)
我能想到这个简单的C#代码,它为您提供当月的最后一个工作日。这只需要周六或周日作为假期。国家特定的当地假期应该手动处理。
private DateTime GetLastBusinessDayOfCurrentMonth()
{
var lastDayOfCurrentMonth = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month));
if(lastDayOfCurrentMonth.DayOfWeek == DayOfWeek.Sunday)
lastDayOfCurrentMonth = lastDayOfCurrentMonth.AddDays(-2);
else if(lastDayOfCurrentMonth.DayOfWeek == DayOfWeek.Saturday)
lastDayOfCurrentMonth = lastDayOfCurrentMonth.AddDays(-1);
return lastDayOfCurrentMonth;
}
答案 4 :(得分:5)
通用,伪代码:
Day day = getLastDayOfMonth
int days = getDaysInMonth
for i = days to 0
if day is weekday
if day is not holiday
return day
end if
end if
day = prevDay
days--
end for
throw exception because no business day was found in the month
答案 5 :(得分:2)
使用LINQ:
public static DateTime GetLastBussinessDayCurrentMonth(DateTime[] holidays)
{
DateTime todayDateTime = DateTime.Today;
return
Enumerable.Range(1, DateTime.DaysInMonth(todayDateTime.Year, todayDateTime.Month))
.Select(day => new DateTime(todayDateTime.Year, todayDateTime.Month, day))
.Where(
dt =>
dt.DayOfWeek != DayOfWeek.Sunday && dt.DayOfWeek != DayOfWeek.Saturday
&& (holidays == null || !holidays.Any(h => h.Equals(dt))))
.Max(d => d.Date);
}
创建包含月中所有可用日期的整数列表
Enumerable.Range(1, DateTime.DaysInMonth(todayDateTime.Year, todayDateTime.Month))
仅过滤不属于周末而且不属于假期的日子
.Where(
dt =>
dt.DayOfWeek != DayOfWeek.Sunday && dt.DayOfWeek != DayOfWeek.Saturday
&& (holidays == null || !holidays.Any(h => h.Equals(dt))))
使用过滤日期
创建新的日期时间 .Select(day => new DateTime(todayDateTime.Year, todayDateTime.Month, day))
.Max(d => d.Date);
答案 6 :(得分:1)
我想出了一个额外的方法,可以用来获得最接近的上一个或当前的工作日,然后可以用它来获取当月的最后一个工作日 - 如果你正在调整周末假期,这也考虑在内:
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<DateTime> UsHolidays(int year, bool adjustForWeekend)
{
return new List<DateTime>()
{
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;
}
答案 7 :(得分:0)
Function GetLastDay(ByVal month As Int32, ByVal year As Int32) As Date
Dim D As New Date(year, month, Date.DaysInMonth(year, month))
For i As Integer = 0 To Date.DaysInMonth(year, month)
Select Case D.AddDays(-i).DayOfWeek
Case DayOfWeek.Saturday, DayOfWeek.Sunday 'Not a weekday
Case Else 'Is a weekday. Flag as first weekday found
Return D.AddDays(-i)
'you can add other code here which could also do a check for holidays or ther stuff since you have a proper date value to look at in the loop
End Select
Next
End Function
答案 8 :(得分:-3)
以下是如何在C#中找到该月的最后一天:
DateTime today = DateTime.Today;
DateTime endOfMonth = new DateTime(today.Year,
today.Month,
DateTime.DaysInMonth(today.Year,
today.Month));