簡體   English   中英

計算前一周的開始和結束日期

[英]Calculate previous week's start and end date

在 C# 中計算前一周開始和結束日期的最佳方法是什么? 即今天 3 月 18 日將導致 3 月 9 日(上周星期一)和 3 月 15 日(上周星期日)。

我已經看到使用 DayOfWeek 和 switch 語句來計算偏移量,但想知道是否有更優雅的方法。

您可以跳過 while 循環並使用

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

這假設您使用星期一作為一周的第一天。

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

閱讀:一次回溯一天,直到我們在本周開始,然后減去七到上周開始。

使用流利的日期時間 https://github.com/FluentDateTime/FluentDateTime

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

當前接受的答案將通過給出本周的星期一而不是最后幾周的星期一而在星期日失敗。 (帶有單元測試輸出的代碼)

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

使用 DayOfWeek 將是實現此目的的一種方式:

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

    DateTime startDate = date;
    DateTime endDate = date.AddDays(7);

您可以創建一個可以與 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);
}

公認的解決方案實際上是不正確的。

您必須在一周“休息”時進行切換,即當它認為一周結束或開始時,並且接受的解決方案中的公式沒有。

這在星期一不像一周開始那么明顯,但如果您將星期四視為本周末,則更是如此。

正確的公式是(以星期四為結束日):

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM