如何确定某个月的最后一个工作日?

时间:2022-10-16 09:46:38

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));

Source

#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));

Source