【问题标题】:Calculate previous week's start and end date计算前一周的开始和结束日期
【发布时间】:2009-03-18 13:59:11
【问题描述】:

在 C# 中计算前一周开始和结束日期的最佳方法是什么? IE。今天 3 月 18 日将导致 3 月 9 日(上周的星期一)和 3 月 15 日(上周的星期日)。

我已经看到使用 DayOfWeek 和一个 switch 语句来计算偏移量,但想知道是否有更优雅的方法。

【问题讨论】:

  • 周五下班后计算上一个工作周的复杂性如何,然后应该返回周五所在的当前周?

标签: c#


【解决方案1】:

你可以跳过while循环并使用

DateTime mondayOfLastWeek = date.AddDays( -(int)date.DayOfWeek - 6 );

这假设您使用星期一作为一周的第一天。

【讨论】:

  • 要回答这个问题,startOfWeek 应该命名为 sundayOfLastWeek。 "日期时间 mondayOfLastWeek = date.AddDays(-(int)date.DayOfWeek - 6);"
  • 不错的一种班轮方法。我认为无论在哪一天运行,以下内容都会起作用: mondayOfLastWeek = DateTime.Now.AddDays( -(int)DateTime.Now.DayOfWeek - 6 ); sundayOfLastWeek = DateTime.Now.AddDays(-(int)DateTime.Now.DayOfWeek);
【解决方案2】:
DayOfWeek weekStart = DayOfWeek.Monday; // or Sunday, or whenever
DateTime startingDate = DateTime.Today;

while(startingDate.DayOfWeek != weekStart)
    startingDate = startingDate.AddDays(-1);

DateTime previousWeekStart = startingDate.AddDays(-7);
DateTime previousWeekEnd = startingDate.AddDays(-1);

阅读:一次回溯一天,直到我们在本周初,然后减去七到上周初。

【讨论】:

    【解决方案3】:

    使用流畅的日期时间https://github.com/FluentDateTime/FluentDateTime

    var dateTime = 1.Weeks().Ago();
    var monday = dateTime.Previous(DayOfWeek.Sunday);
    var sunday = dateTime.Next(DayOfWeek.Sunday);
    

    【讨论】:

      【解决方案4】:

      使用 DayOfWeek 将是实现此目的的一种方式:

          DateTime date = DateTime.Now.AddDays(-7);
          while (date.DayOfWeek != DayOfWeek.Monday)
          {
              date = date.AddDays(-1);
          }
      
          DateTime startDate = date;
          DateTime endDate = date.AddDays(7);
      

      【讨论】:

        【解决方案5】:

        当前接受的答案将在周日失败,因为给出本周的周一而不是上周的周一。 (带有单元测试输出的代码)

        DateTime mondayOfLastWeek = date.AddDays( -(int)date.DayOfWeek - 6 );
        //Failed to get start of last-week from date-time: 2020-03-01T00:00:00.0000000Z
        //  Expected: 2020-02-17 00:00:00.000
        //  But was:  2020-02-24 00:00:00.000
        

        以下代码解决了这个问题:

        var dayOfWeek = (int) date.DayOfWeek - 1;
        if (dayOfWeek < 0) dayOfWeek = 6;
        
        var thisWeeksMonday = date.AddDays(-dayOfWeek).Date;
        var lasWeeksMonday = thisWeeksMonday.AddDays(-7);
        

        如果您愿意,可以将其简化为单行代码(我不建议使用这种几乎不可读的代码...):

        var mondayOfLastWeek  = date.AddDays(-(7 + ((int)date.DayOfWeek - 1 == -1 ? 6 : (int)date.DayOfWeek - 1)));
        

        【讨论】:

          【解决方案6】:

          您可以创建一个可与 DayOfWeek 参数一起使用的 DateTime 扩展方法:

          public static class DateTimeExtension
          {
              public static DateTime GetPreviousWeekDay(this DateTime currentDate, DayOfWeek dow)
              {
                  int currentDay = (int)currentDate.DayOfWeek, gotoDay = (int)dow;
                  return currentDate.AddDays(-7).AddDays(gotoDay-currentDay);
              }        
          }
          

          然后按如下方式使用:

          DateTime testDate = new DateTime(2017, 01, 21);
                  
          Console.WriteLine(testDate.GetPreviousWeekDay(DayOfWeek.Sunday));
          Console.WriteLine(testDate.GetPreviousWeekDay(DayOfWeek.Saturday));
          

          要使用它来获取当前日期的前一周(如问题中所述):

          var prevWkStartDate = DateTime.Now.GetPreviousWeekDay(DayOfWeek.Monday); 
          var prevWkEndDate = DateTime.Now.GetPreviousWeekDay(DayOfWeek.Sunday);
          Console.Write($"Previous week starts at {prevWkStartDate.ToShortDateString()}");
          Console.WriteLine($" and ends at {prevWkEndDate.ToShortDateString()}");
          

          更新:似乎这需要修复(示例日期:2020 年 12 月 10 日):

          public static DateTime GetPreviousWeekDay(this DateTime currentDate, DayOfWeek dow)
          {
              int d = 0; if (dow == DayOfWeek.Sunday) { dow = DayOfWeek.Saturday; d = 1; }
              int currentDay = (int)currentDate.DayOfWeek, gotoDay = (int)dow;
              return currentDate.AddDays(-7).AddDays(gotoDay - currentDay + d);
          }
          

          【讨论】:

            【解决方案7】:

            公认的解决方案实际上是不正确的。

            您必须在一周“休息”时切换,即当它认为一周结束或开始时,并且接受的解决方案中的公式没有。

            这在星期一不像一周的开始那么明显,但如果您将星期四视为一周的结束,则更是如此。

            正确的公式是(以星期四为结束日):

            DateTime thu = date.AddDays(-(int)(date.AddDays(-5).DayOfWeek) -1);
            

            对于星期一,-5 将切换为 -2。

            打印示例代码

                    String s = "";
                    DateTime date = new DateTime(2017, 1, 1);
                    for (int i = 0; i < 14; i++)
                    {
                        date = date.AddDays(1);
                        DateTime thu = date.AddDays(-(int)(date.AddDays(-5).DayOfWeek) -1);
                        DateTime mon = date.AddDays(-(int)(date.AddDays(-2).DayOfWeek) -1);
                        s += date.ToString() + " - Thu: " + thu.ToString() + " - Mon: " + mon.ToString() + "\r\n";
                    }
                    Console.WriteLine(s);
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2012-07-25
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-07-23
              相关资源
              最近更新 更多