【问题标题】:How to get last Friday of month(s) using .NET如何使用 .NET 获取每月的最后一个星期五
【发布时间】:2010-04-26 05:56:23
【问题描述】:

我有一个函数只返回一系列日期中的星期五

public static List<DateTime> GetDates(DateTime startDate, int weeks)
{
    int days = weeks * 7;

    //Get the whole date range 
    List<DateTime> dtFulldateRange = Enumerable.Range(-days, days).Select(i => startDate.AddDays(i)).ToList();

    //Get only the fridays from the date range
    List<DateTime> dtOnlyFridays = (from dtFridays in dtFulldateRange
                                    where dtFridays.DayOfWeek == DayOfWeek.Friday
                                    select dtFridays).ToList();
    return dtOnlyFridays;
}

函数的目的: "从指定的周数到 StartDate 的日期列表,即如果 startdate 是 2010 年 4 月 23 日并且周数是 1,那么程序应该返回从2010 年 4 月 16 日至开始日期”。

我将函数调用为:

DateTime StartDate1 = DateTime.ParseExact("20100430", "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture);
List<DateTime> dtList = Utility.GetDates(StartDate1, 4).ToList();

现在要求发生了一些变化。我只需要找出每个月的最后一个星期五。 函数的输入将保持不变。

【问题讨论】:

  • @Newbie:C# 的版本很重要,.NET 的版本也很重要,因为 C# 本身不能帮助你——你需要 .NET Framework。
  • 更惯用的实现是使用IEnumerable&lt;DateTime&gt;,而不是将所有内容都转换为List&lt;DateTime&gt;。

标签: c# .net c#-3.0


【解决方案1】:

您已经拥有给定范围内的星期五列表。现在只需像这样再次查询:

List<DateTime> lastFridays = (from day in fridays
                              where day.AddDays(7).Month != day.Month
                              select day).ToList<DateTime>();

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    对于那些(像我一样)步入这个问题的人来说,Sarath 的答案只是一个小小的改进

    private DateTime GetLastFridayOfTheMonth(DateTime date)
    {
        var lastDayOfMonth = new DateTime(date.Year, date.Month, DateTime.DaysInMonth(date.Year, date.Month));
    
        while (lastDayOfMonth.DayOfWeek != DayOfWeek.Friday)
            lastDayOfMonth = lastDayOfMonth.AddDays(-1);
    
        return lastDayOfMonth;
    }
    

    【讨论】:

      【解决方案3】:

      这是我们正在使用的扩展方法。

      public static class DateTimeExtensions
      {
          public static DateTime GetLastFridayInMonth(this DateTime date)
          {
              var firstDayOfNextMonth = new DateTime(date.Year, date.Month, 1).AddMonths(1);
              int vector = (((int)firstDayOfNextMonth.DayOfWeek + 1) % 7) + 1;
              return firstDayOfNextMonth.AddDays(-vector);
          }
      }
      

      下面是 MbUnit 测试用例

      [TestFixture]
      public class DateTimeExtensionTests
      {
        [Test]
        [Row(1, 2011, "2011-01-28")]
        [Row(2, 2011, "2011-02-25")]
        ...
        [Row(11, 2011, "2011-11-25")]
        [Row(12, 2011, "2011-12-30")]
        [Row(1, 2012, "2012-01-27")]
        [Row(2, 2012, "2012-02-24")]
        ...
        [Row(11, 2012, "2012-11-30")]
        [Row(12, 2012, "2012-12-28")]
      
        public void Test_GetLastFridayInMonth(int month, int year, string expectedDate)
        {
          var date = new DateTime(year, month, 1);
          var expectedValue = DateTime.Parse(expectedDate);
      
          while (date.Month == month)
          {
            var result = date.GetLastFridayInMonth();
            Assert.AreEqual(expectedValue, result);
            date = date.AddDays(1);
          }
        }
      }
      

      【讨论】:

        【解决方案4】:

        检查下个月的第一天是星期几,然后减去足够的天数得到星期五。

        或者,如果您已经有一个星期五列表,则只返回那些加上 7 天得出下个月日期的那些。

        【讨论】:

          【解决方案5】:

          根据 DeBorges 的回答,这是获取任何特定日期的扩展

          public static DateTime GetLastSpecificDayOfTheMonth(this DateTime date, DayOfWeek dayofweek)
              {
                  var lastDayOfMonth = new DateTime(date.Year, date.Month, DateTime.DaysInMonth(date.Year, date.Month));
          
                  while (lastDayOfMonth.DayOfWeek != dayofweek)
                      lastDayOfMonth = lastDayOfMonth.AddDays(-1);
          
                  return lastDayOfMonth;
              }
          

          【讨论】:

            【解决方案6】:

            通过将日期作为参数发送来调用以下函数,其中它从日期参数中提取月份和年份,并返回该月的最后一个Friday

            public DateTime GetLastFridayOfMonth(DateTime dt)
            {
                  DateTime dtMaxValue = DateTime.MaxValue;
                  DateTime dtLastDayOfMonth = new DateTime(dt.Year, dt.Month, DateTime.DaysInMonth(dt.Year, dt.Month));
            
                  while (dtMaxValue == DateTime.MaxValue)
                  {
                       // Returns if the decremented day is the fisrt Friday from last(ie our last Friday)
                       if (dtMaxValue == DateTime.MaxValue && dtLastDayOfMonth.DayOfWeek == DayOfWeek.Friday)
                           return dtLastDayOfMonth;
                       // Decrements last day by one
                       else
                          dtLastDayOfMonth = dtLastDayOfMonth.AddDays(-1.0);
                  }
                  return dtLastDayOfMonth;
            }
            

            【讨论】:

            • 为什么在这里使用 DateTime.MaxValue?
            • @ColinM 好像是作为常量使用的。这和while (true) { ... } 一样,虽然看起来很笨重。它还包含不必要的检查值是否已更改。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多