繁体   English   中英

在 C# 中获取上/下周星期三的日期

[英]Get last/next week Wednesday date in C#

我如何在 C# 中获得上周星期三和下星期三的日期:

public Form1()
{
   InitializeComponent();
   CurrentDate.Text = "Today's Date: " + DateTime.Now.ToString("dd/MM/yyyy");
   CurrentRent.Text = "Current Rent Date: "; // last wednesday
   NextRent.Text = "Next Rent Date: "; // next wednesday
}

要找到下一个星期三,只需不断添加天数直到找到。 要找到前一个星期三,只需不断减去天数,直到得到一天。

DateTime nextWednesday = DateTime.Now.AddDays(1);
while (nextWednesday.DayOfWeek != DayOfWeek.Wednesday)
    nextWednesday = nextWednesday.AddDays(1);
DateTime lastWednesday = DateTime.Now.AddDays(-1);
while (lastWednesday.DayOfWeek != DayOfWeek.Wednesday)
    lastWednesday = lastWednesday.AddDays(-1);

使用 AddDays 例程:

        // increment by the number of offset days to get the correct date
        DayOfWeek desiredDay = DayOfWeek.Wednesday;
        int offsetAmount = (int) desiredDay - (int) DateTime.Now.DayOfWeek;
        DateTime lastWeekWednesday = DateTime.Now.AddDays(-7 + offsetAmount);
        DateTime nextWeekWednesday = DateTime.Now.AddDays(7 + offsetAmount);

应该这样做!

注意:如果是星期一,“上个星期三”会给你发生的最后一个星期三,但“下星期三”会给你从现在起 9 天后的星期三! 如果您想在两天内获得星期三,则需要使用“%”运算符。 这意味着第二个“下周”语句将读取“(7 + offsetAmount) % 7”。

DateTime.Now.AddDays(7)DateTime.Now.AddDays(-7)是你如何做算术的,假设你是在星期三。 如果不是,您需要做的是使用DayOfWeek属性来确定您需要确定哪一天是“星期三”所需的天数(正数和负数)。 然后您可以将该值传递给AddDays

例如,如果今天是星期二,则上周三为AddDays(-6) AddDays(8) ,下周三为AddDays(8)

我会把计算这些的任务留给你。

您可以创建 2 个 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);
    }

    public static DateTime GetNextWeekDay(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.Wednesday));
Console.WriteLine(testDate.GetNextWeekDay(DayOfWeek.Wednesday));

您可以使用它来计算它:

DateTime day = DateTime.Today;
while (day.DayOfWeek != DayOfWeek.Wednesday)
    day = day.AddDays(-1);
var currentRent = day;
var nextRent = day.AddDays(7);

请注意,如果今天是星期三,则会将currentRent显示为今天,而不是将nextRent为今天。 如果你想颠倒这个,你可以颠倒逻辑。

DateTime day = DateTime.Today;
while (day.DayOfWeek != DayOfWeek.Wednesday)
    day = day.AddDays(1);
var currentRent = day.AddDays(-7);
var nextRent = day;

根据 Servy 的回答,这里有一个扩展方法,它将返回所需的日期/日期:

    public static DateTime GetPrevious(this DateTime date, DayOfWeek dayOfWeek)
    {
        var lastDay = date.AddDays(-1);
        while (lastDay.DayOfWeek != dayOfWeek)
        {
            lastDay = lastDay.AddDays(-1);
        }

        return lastDay;
    }

    public static DateTime GetNext(this DateTime date, DayOfWeek dayOfWeek)
    {
        var nextDay = date.AddDays(+1);
        while (nextDay.DayOfWeek != dayOfWeek)
        {
            nextDay = nextDay.AddDays(+1);
        }

        return nextDay;
    }

您需要使用DayOfWeek枚举以及 switch 语句的 if-else 结构来确定为您的日期添加/减去多少天。 这是繁琐的编码,但很简单。

DateTime nextRent;
DateTime lastRent;
DateTime today = DateTime.Now;

if (today.DayOfWeek == DayOfWeek.Wednesday)
{
   nextRent = today.AddDays(7);
   lastRent = today.AddDays(-7);
}
else if (today.DayOfWeek == DayOfWeek.Thursday)
{
   nextRent = today.AddDays(6);
   lastRent = today.AddDays(-8);
}
//ect for all days

这将起作用。 您需要计算您提供的日期与最近的星期三之间的天数差异,并根据差异是否大于零来计算上一个/下一个星期三。

int difference = date.DayOfWeek - DayOfWeek.Wednesday;
DateTime lastWednesday = difference > 0 ? date.AddDays(-1 * difference) : date.AddDays(-1 * (7 + difference));
DateTime nextWednesday = lastWednesday.AddDays(7);

一些答案的问题之一是 DayoyOfWeek 是一个值为 0-6 的枚举。 当一周中的随后一天等于星期日(枚举值 = 0),但您给出了星期二(枚举值 = 2),并且您想要下一个星期二时,如果您只是执行计算,则计算会出错。

我自己在我正在从事的项目中使用的具有两种方法的类是。

public static class DateHelper
{
    public static DateTime GetDateForLastDayOfWeek(DayOfWeek DOW, DateTime DATE)
    {
        int adjustment = ((int)DATE.DayOfWeek < (int)DOW ? 7 : 0);
        return DATE.AddDays(0- (((int)(DATE.DayOfWeek) + adjustment) - (int)DOW));
    }

    public static DateTime GetDateForNextDayOfWeek(DayOfWeek DOW, DateTime DATE)
    {
        int adjustment = ((int)DATE.DayOfWeek < (int)DOW ? 0 : 7);
        return DATE.AddDays(((int)DOW) - ((int)(DATE.DayOfWeek)) + adjustment);
    }
}

XUnit 测试证明上述代码有效。

public class DateHelperUnitTests
{

    [Theory]
    [InlineData(2020, 1, 7, 2020, 1, 7)]
    [InlineData(2020, 1, 8,  2020, 1, 7)]
    [InlineData(2020, 1, 9,  2020, 1, 7)]
    [InlineData(2020, 1, 10, 2020, 1, 7)]
    [InlineData(2020, 1, 11, 2020, 1, 7)]
    [InlineData(2020, 1, 12, 2020, 1, 7)]
    [InlineData(2020, 1, 13, 2020, 1, 7)]
    [InlineData(2020, 1, 14, 2020, 1, 14)]
    [InlineData(2020, 1, 15, 2020, 1, 14)]
    public void GetDateForLastDayOfWeek_MultipleValues_Pass(
        int InputYear, int InputMonth, int InputDay,
        int ExpectedYear, int ExpectedMonth, int ExpectedDay)
    {
        DateTime DateToTest = new DateTime(InputYear, InputMonth, InputDay);
        DateTime NewDate = DateHelper.GetDateForLastDayOfWeek(DayOfWeek.Tuesday, DateToTest);
        DateTime DateExpected = new DateTime(ExpectedYear,ExpectedMonth,ExpectedDay);

        Assert.True(0 == DateTime.Compare(DateExpected.Date, NewDate.Date));
    }

    [Theory]
    [InlineData(2020, 1, 7, 2020, 1, 14)]
    [InlineData(2020, 1, 8, 2020, 1, 14)]
    [InlineData(2020, 1, 9, 2020, 1, 14)]
    [InlineData(2020, 1, 10, 2020, 1, 14)]
    [InlineData(2020, 1, 11, 2020, 1, 14)]
    [InlineData(2020, 1, 12, 2020, 1, 14)]
    [InlineData(2020, 1, 13, 2020, 1, 14)]
    [InlineData(2020, 1, 14, 2020, 1, 21)]
    [InlineData(2020, 1, 15, 2020, 1, 21)]
    public void GetDateForNextDayOfWeek_MultipleValues_Pass(
        int InputYear, int InputMonth, int InputDay,
        int ExpectedYear, int ExpectedMonth, int ExpectedDay)
    {
        DateTime DateToTest = new DateTime(InputYear, InputMonth, InputDay);
        DateTime NewDate = DateHelper.GetDateForNextDayOfWeek(DayOfWeek.Tuesday, DateToTest);
        DateTime DateExpected = new DateTime(ExpectedYear, ExpectedMonth, ExpectedDay);

        Assert.True(0 == DateTime.Compare(DateExpected.Date, NewDate.Date));
    }
}

改进了来自 Servy 的答案。 您需要实际将 nextWednesday 或 lastWednesday 日期设置为 while 循环中的新日期,否则会进入无限循环

DateTime nextWednesday = DateTime.Now.AddDays(1);
while (nextWednesday.DayOfWeek != DayOfWeek.Wednesday)
    nextWednesday = nextWednesday.AddDays(1);
DateTime lastWednesday = DateTime.Now.AddDays(-1);
while (lastWednesday.DayOfWeek != DayOfWeek.Wednesday)
    lastWelastWednesday.AddDays(-1);
    private static DateTime FindPreviousDayOfWeek(DateTime fromDate, DayOfWeek findDay, 
        bool skipSame = false)
    {
        if (fromDate.DayOfWeek < findDay)
            fromDate = fromDate.AddDays(-((int)fromDate.DayOfWeek - 1 + (int)findDay));
        else if (fromDate.DayOfWeek > findDay)
            fromDate = fromDate.AddDays(-((int)fromDate.DayOfWeek - (int)findDay));
        else if (fromDate.DayOfWeek == findDay && skipSame == true)
            fromDate = fromDate.AddDays(-7);

        return fromDate;
    }

如果当前日期与所需日期相同,则 skipSame 变量不包括当前日期。

这是一个单线来完成相同的任务。 理解它实际上是如何工作的有点令人难以置信,但它确实如此:

下周三获取:

 dt.AddDays(-(int)(dt.AddDays(-4).DayOfWeek) + 6);

获取上周三

 dt.AddDays(-(int)(dt.AddDays(-3).DayOfWeek));

在这两种情况下,它都会在星期三时返回当天本身。 这适用于任何工作日,只需调整 AddDays() 调用中的数字。 以周五为例:

获得下周五

 dt.AddDays(-(int)(dt.AddDays(-6).DayOfWeek) + 6);

获取上周五

 dt.AddDays(-(int)(dt.AddDays(-5).DayOfWeek));

这个扩展方法应该适用于任何一天

   public static class DateTimeExtensions
    {
        public static DateTime LastDayOfWeek(this DateTime _date, DayOfWeek dayofweek)
        {
            return _date.AddDays(-1 * ((_date.DayOfWeek - dayofweek) % 7)).Date;
        }

        public static DateTime NextDayOfWeek(this DateTime _date, DayOfWeek dayofweek)
        {
            return _date.LastDayOfWeek(dayofweek).AddDays(7).Date;
        }
    }

用法

var lastWendsday = DateTime.Now.LastDayOfWeek(DayOfWeek.Wednesday);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM