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

时间:2008-11-07 18:16:49

标签: .net

如何计算.NET中该月的最后一个工作日?

9 个答案:

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

Source