How can I calculate the last business day of the month in .NET?
如何计算.NET中该月的最后一个工作日?
9 个解决方案
#1
9
I would do it like this for a Monday through Friday business week:
对于周一到周五的工作周,我会这样做:
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
13
Assuming business days are monday to friday (this doesn't account for holidays), this function should return the proper answer:
假设工作日是星期一到星期五(这不考虑假期),这个函数应该返回正确的答案:
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
#3
6
First, get the last day of the month. Then keep decrementing until you're either past the beginning of the month, or have hit a date that validates as a "business day".
首先,获取本月的最后一天。然后继续递减,直到你要么超过月初,要么达到验证为“营业日”的日期。
#4
6
I could think of this simple C# code which gives you the last business day of current month. This only takes Saturday or Sunday as holidays. Country specific local holidays should be handled manually.
我能想到这个简单的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;
}
#5
5
general purpose, pseudocode:
通用,伪代码:
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
#6
1
I came up with an additional method that can be used to get the closest previous or current business day which can then be used to get the last business day of the month - this also takes into account if you are adjusting for weekend holidays:
我想出了一个额外的方法,可以用来获得最接近的前一个或当前的工作日,然后可以用来获得一个月的最后一个工作日 - 如果你正在调整周末假期,这也会考虑到:
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;
}
I also use the US holidays in my calculation which I get from the following code I developed from looking at this post: http://geekswithblogs.net/wpeck/archive/2011/12/27/us-holiday-list-in-c.aspx
我也在我的计算中使用了美国假期,我从下面的代码中看到了这一点:http://geekswithblogs.net/wpeck/archive/2011/12/27/us-holiday-list-in- c.aspx
The code can be seen here for that:
这里可以看到代码:
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
1
Using 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);
}
Explaining
Creating a list of integers with all days available in month
创建一个包含月中所有可用日期的整数列表
Enumerable.Range(1, DateTime.DaysInMonth(todayDateTime.Year, todayDateTime.Month))
Filtering only days that do not fall on weekends and do not fall on holidays
仅过滤不在周末而且不在假期的日子
.Where(
dt =>
dt.DayOfWeek != DayOfWeek.Sunday && dt.DayOfWeek != DayOfWeek.Saturday
&& (holidays == null || !holidays.Any(h => h.Equals(dt))))
Create new datetime with the filtered dates
使用筛选日期创建新的日期时间
.Select(day => new DateTime(todayDateTime.Year, todayDateTime.Month, day))
.Max(d => d.Date);
#8
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
#9
-3
Here is how to find the last day of the month in C#:
以下是如何在C#中找到该月的最后一天:
DateTime today = DateTime.Today;
DateTime endOfMonth = new DateTime(today.Year,
today.Month,
DateTime.DaysInMonth(today.Year,
today.Month));
#1
9
I would do it like this for a Monday through Friday business week:
对于周一到周五的工作周,我会这样做:
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
13
Assuming business days are monday to friday (this doesn't account for holidays), this function should return the proper answer:
假设工作日是星期一到星期五(这不考虑假期),这个函数应该返回正确的答案:
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
#3
6
First, get the last day of the month. Then keep decrementing until you're either past the beginning of the month, or have hit a date that validates as a "business day".
首先,获取本月的最后一天。然后继续递减,直到你要么超过月初,要么达到验证为“营业日”的日期。
#4
6
I could think of this simple C# code which gives you the last business day of current month. This only takes Saturday or Sunday as holidays. Country specific local holidays should be handled manually.
我能想到这个简单的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;
}
#5
5
general purpose, pseudocode:
通用,伪代码:
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
#6
1
I came up with an additional method that can be used to get the closest previous or current business day which can then be used to get the last business day of the month - this also takes into account if you are adjusting for weekend holidays:
我想出了一个额外的方法,可以用来获得最接近的前一个或当前的工作日,然后可以用来获得一个月的最后一个工作日 - 如果你正在调整周末假期,这也会考虑到:
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;
}
I also use the US holidays in my calculation which I get from the following code I developed from looking at this post: http://geekswithblogs.net/wpeck/archive/2011/12/27/us-holiday-list-in-c.aspx
我也在我的计算中使用了美国假期,我从下面的代码中看到了这一点:http://geekswithblogs.net/wpeck/archive/2011/12/27/us-holiday-list-in- c.aspx
The code can be seen here for that:
这里可以看到代码:
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
1
Using 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);
}
Explaining
Creating a list of integers with all days available in month
创建一个包含月中所有可用日期的整数列表
Enumerable.Range(1, DateTime.DaysInMonth(todayDateTime.Year, todayDateTime.Month))
Filtering only days that do not fall on weekends and do not fall on holidays
仅过滤不在周末而且不在假期的日子
.Where(
dt =>
dt.DayOfWeek != DayOfWeek.Sunday && dt.DayOfWeek != DayOfWeek.Saturday
&& (holidays == null || !holidays.Any(h => h.Equals(dt))))
Create new datetime with the filtered dates
使用筛选日期创建新的日期时间
.Select(day => new DateTime(todayDateTime.Year, todayDateTime.Month, day))
.Max(d => d.Date);
#8
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
#9
-3
Here is how to find the last day of the month in C#:
以下是如何在C#中找到该月的最后一天:
DateTime today = DateTime.Today;
DateTime endOfMonth = new DateTime(today.Year,
today.Month,
DateTime.DaysInMonth(today.Year,
today.Month));