代码之家  ›  专栏  ›  技术社区  ›  Henryk

计算前一周的开始和结束日期

c#
  •  36
  • Henryk  · 技术社区  · 16 年前

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

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

    7 回复  |  直到 16 年前
        1
  •  74
  •   bstoney    16 年前

    您可以跳过while循环并使用

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

        2
  •  32
  •   mqp    16 年前
    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);
    

    阅读:一次回顾一天,直到本周开始,然后减去7,直到上周开始。

        3
  •  13
  •   Simon Randy Burden    11 年前

    使用Fluent DateTime https://github.com/FluentDateTime/FluentDateTime

    var dateTime = 1.Weeks().Ago();
    var monday = dateTime.Previous(DayOfWeek.Sunday);
    var sunday = dateTime.Next(DayOfWeek.Sunday);
    
        4
  •  3
  •   Andy Rose    16 年前

    使用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
  •  3
  •   Martin    6 年前

    当前已接受的答案将在星期天失败,因为它将给出当前星期的星期一,而不是最后一周的星期一。 (带有单元测试输出的代码)

    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
  •  2
  •   Matt    4 年前

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

    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
  •  0
  •   nepdev    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);