计算一个月的最后一天DayOfWeek

时间:2009-03-08 11:49:45

标签: c# datetime

鉴于DateTime和DayOfWeek应该返回该月的最后一个DayOfWeek的日期。

E.g。 2009年3月1日和周日将于2009年3月29日回归

9 个答案:

答案 0 :(得分:12)

找不到方便的单行,但这个有效:

static DateTime LastDayOfWeekInMonth(DateTime day, DayOfWeek dow)
{
    DateTime lastDay = new DateTime(day.Year, day.Month, 1).AddMonths(1).AddDays(-1);
    DayOfWeek lastDow = lastDay.DayOfWeek;

    int diff = dow - lastDow;

    if (diff > 0) diff -= 7;

    System.Diagnostics.Debug.Assert(diff <= 0);

    return lastDay.AddDays(diff);
}

答案 1 :(得分:11)

http://datetimeextensions.codeplex.com/有一个Last(dayOfWeek)扩展方法,可以为您执行此操作

测试包括: - )

答案 2 :(得分:6)

获取下个月的第一天,然后找到该月的第一个工作日。回到七天,你就是在正确月份的最后一周的那个工作日:

DateTime date = new DateTime(2009, 3, 12);
DayOfWeek day = DayOfWeek.Sunday;

DateTime nextMonth = new DateTime(date.Year, date.Month, 1).AddMonths(1);
while (nextMonth.DayOfWeek != day) {
    nextMonth = nextMonth.AddDays(1);
}
DateTime lastInMonth = nextMonth.AddDays(-7);

(您可以使用一些算法来替换循环,该算法根据DayOfWeek值的数值计算要添加的天数,但这更直接。)

编辑:
您当然也可以在当月的最后一天获得,然后向后循环,直到找到正确的工作日。

答案 3 :(得分:4)

static DateTime LastDateOfWeekForMonth(DayOfWeek weekday, int month, int year)
{
    DateTime d = new DateTime(year, month, 1).AddMonths(1);
    while (!(d.DayOfWeek == weekday && d.Month == month))
    {
       d = d.AddDays(-1);
    }
    return d;
}

答案 4 :(得分:1)

试试这个:从最后一天开始算起,直到你找到你想要的那天

static DateTime LastOccurenceOfDay(DateTime dt, DayOfWeek dow)
    {
        DateTime looperDate = new DateTime(dt.Year, dt.Month, 1)
                                     .AddMonths(1).AddDays(-1);
        while (looperDate.DayOfWeek!=dow)                            
            looperDate =looperDate.AddDays(-1);            
        return looperDate;

编辑: 恢复了Dangph在评论中引用的旧版本。

  static DateTime LastOccurenceOfDay(DateTime dt, DayOfWeek dow)
     {
         //set start of loop
         DateTime looperDate = new DateTime(dt.Year, dt.Month, 1); 
         //initialze return value
         DateTime returnDate = dt;
         //loop until the month is over
         while (looperDate.Month == dt.Month)
         {
             //if the current DayOfWeek is the date you're looking for
             if (looperDate.DayOfWeek == dow) 
                 //remember it.
                 returnDate = looperDate;
             //increase day
             looperDate=looperDate.AddDays(1);
         }
         return returnDate;
     }

答案 5 :(得分:1)

    public DateTime GetLastDayOfMonth(int year, int month, DayOfWeek dayOfWeek)
    {
        var daysInMonth = DateTime.DaysInMonth(year, month);
        var lastDay = new DateTime(year, month, daysInMonth);

        while (lastDay.DayOfWeek != dayOfWeek)
        {
            lastDay = lastDay.AddDays(-1);
        }

        return lastDay;
    }

答案 6 :(得分:1)

以下是LastDayOfMonth()和LastDayOfMonth(DayOfWeek)以及单元测试,其灵感来自@Paul Fryer在How to find the 3rd Friday in a month with C#?中的“Last Friday ”实现:

/**
    /// <summary>An extension method that returns the last day of the month.</summary>
    /// <param name="d">A date within the month to calculate.</param>
    /// <returns>The last day of the current month.</returns>
    **/
    public static DateTime LastDayOfMonth(this DateTime d)
    {
        DateTime nextMonth = new DateTime(d.Year, d.Month, 1).AddMonths(1);
        return nextMonth.AddDays(-1);
    }

    /**
    /// <summary>An extension method that returns the last <see cref="DayOfWeek"> of the month.</summary>
    /// <param name="d">A date within the month to calculate.</param>
    /// <returns>The last day of the current month.</returns>
    **/
    public static DateTime LastDayOfMonth(this DateTime d, DayOfWeek dayOfWeek)
    {
        DateTime lastDayOfMonth = d.LastDayOfMonth();
        int vector = (((int)lastDayOfMonth.DayOfWeek - (int)dayOfWeek + DaysInWeek) % DaysInWeek);
        return lastDayOfMonth.AddDays(-vector);
    }

 #region LastDayOfMonth Tests

    [TestCase("1/1/2011", "1/31/2011")]
    [TestCase("2/1/2009", "2/28/2009")] //Leap Year
    [TestCase("2/1/2008", "2/29/2008")] //Leap Year
    [TestCase("3/10/2011", "3/31/2011")]
    [TestCase("4/20/2011", "4/30/2011")]
    [TestCase("5/15/2011", "5/31/2011")]
    [TestCase("6/30/2011", "6/30/2011")]
    [TestCase("12/1/2011", "12/31/2011")]
    public void LastDayOfMonthReturnsCorrectDay(string startingDate, string expectedDate)
    {
        //Arrange
        DateTime testDate = DateTime.Parse(startingDate);
        DateTime expected = DateTime.Parse(expectedDate);

        //Act
        DateTime actual = testDate.LastDayOfMonth();

        //Assert
        Assert.That(actual, Is.EqualTo(expected));
    }

    [TestCase("1/1/2011", DayOfWeek.Monday, "1/31/2011")]
    [TestCase("2/1/2009", DayOfWeek.Saturday, "2/28/2009")]
    [TestCase("2/1/2009", DayOfWeek.Sunday, "2/22/2009")] 
    [TestCase("2/1/2008", DayOfWeek.Friday, "2/29/2008")] //Leap Year
    [TestCase("2/1/2008", DayOfWeek.Thursday, "2/28/2008")] //Leap Year
    [TestCase("3/10/2011", DayOfWeek.Wednesday, "3/30/2011")]
    [TestCase("4/20/2011", DayOfWeek.Friday, "4/29/2011")]
    [TestCase("4/20/2011", DayOfWeek.Saturday, "4/30/2011")]
    [TestCase("5/15/2011", DayOfWeek.Tuesday, "5/31/2011")]
    [TestCase("5/15/2011", DayOfWeek.Saturday, "5/28/2011")]
    [TestCase("9/30/2011", DayOfWeek.Sunday, "9/25/2011")]
    [TestCase("12/1/2011", DayOfWeek.Monday, "12/26/2011")]
    public void LastDayOfMonthReturnsCorrectDayOfWeek(string startingDate, DayOfWeek dayOfWeek, string expectedDate)
    {
        //Arrange
        DateTime testDate = DateTime.Parse(startingDate);
        DateTime expected = DateTime.Parse(expectedDate);

        //Act
        DateTime actual = testDate.LastDayOfMonth(dayOfWeek);

        //Assert
        Assert.That(actual, Is.EqualTo(expected));
    }       

    #endregion

答案 7 :(得分:0)

static DateTime GetDayOfWeekInMonthFromWeekIndex(this DateTime date, DayOfWeek dow, int weekIndex)
{
    if (weekIndex > 4)
        return LastDayOfWeekInMonth(date, dow);

    DateTime newDate = new DateTime(date.Year, date.Month, 1);
    DayOfWeek newDow = newDate.DayOfWeek;
    int diff = dow - newDow;
    diff += ((weekIndex - 1) * 7);
    return newDate.AddDays(diff);
}

答案 8 :(得分:0)

值得一提的是

int LastDayOfMonth = DateTime.DaysInMonth(now.year,now.month);