C# Datetime-下周二开始

C# Datetime-下周二开始,c#,.net,date,C#,.net,Date,我怎样才能知道下星期二的日期 在PHP中,它就像strotime(“下周二”)一样简单 如何在.NET中实现类似的功能这应该可以做到: DateTime nextTuesday = DateTime.Today.AddDays(((int)DateTime.Today.DayOfWeek - (int)DayOfWeek.Tuesday) + 7); static DateTime GetNextWeekday(DayOfWeek day) { DateTime result = Da

我怎样才能知道下星期二的日期

在PHP中,它就像
strotime(“下周二”)一样简单


如何在.NET中实现类似的功能这应该可以做到:

DateTime nextTuesday = DateTime.Today.AddDays(((int)DateTime.Today.DayOfWeek - (int)DayOfWeek.Tuesday) + 7);
static DateTime GetNextWeekday(DayOfWeek day)
{
    DateTime result = DateTime.Now.AddDays(1);
    while( result.DayOfWeek != day )
        result = result.AddDays(1);
    return result;
}

正如我在评论中提到的,您可以用“下周二”来表示各种事情,但此代码为您提供了“下周二发生的时间,或者如果已经是周二,则为今天”:

如果已经是星期二,您想给“一周时间”,可以使用:

// This finds the next Monday (or today if it's Monday) and then adds a day... so the
// result is in the range [1-7]
int daysUntilTuesday = (((int) DayOfWeek.Monday - (int) today.DayOfWeek + 7) % 7) + 1;
。。。或者你可以使用原始公式,但从明天开始:

DateTime tomorrow = DateTime.Today.AddDays(1);
// The (... + 7) % 7 ensures we end up with a value in the range [0, 6]
int daysUntilTuesday = ((int) DayOfWeek.Tuesday - (int) tomorrow.DayOfWeek + 7) % 7;
DateTime nextTuesday = tomorrow.AddDays(daysUntilTuesday);
编辑:只是为了让它变得漂亮和多功能:

public static DateTime GetNextWeekday(DateTime start, DayOfWeek day)
{
    // The (... + 7) % 7 ensures we end up with a value in the range [0, 6]
    int daysToAdd = ((int) day - (int) start.DayOfWeek + 7) % 7;
    return start.AddDays(daysToAdd);
}
因此,要获得“今天或未来6天”的值:

要获取“下周二(不包括今天)”的值,请执行以下操作:


对于这个问题,有一些不那么冗长、更聪明/优雅的解决方案,但下面的C#函数在许多情况下都非常有效

/// <summary>
/// Find the closest weekday to the given date
/// </summary>
/// <param name="includeStartDate">if the supplied date is on the specified day of the week, return that date or continue to the next date</param>
/// <param name="searchForward">search forward or backward from the supplied date. if a null parameter is given, the closest weekday (ie in either direction) is returned</param>
public static DateTime ClosestWeekDay(this DateTime date, DayOfWeek weekday, bool includeStartDate = true, bool? searchForward=true)
{
    if (!searchForward.HasValue && !includeStartDate) 
    {
        throw new ArgumentException("if searching in both directions, start date must be a valid result");
    }
    var day = date.DayOfWeek;
    int add = ((int)weekday - (int)day);
    if (searchForward.HasValue)
    {
        if (add < 0 && searchForward.Value)
        {
            add += 7;
        }
        else if (add > 0 && !searchForward.Value)
        {
            add -= 7;
        }
        else if (add == 0 && !includeStartDate)
        {
            add = searchForward.Value ? 7 : -7;
        }
    }
    else if (add < -3) 
    {
        add += 7; 
    }
    else if (add > 3)
    {
        add -= 7;
    }
    return date.AddDays(add);
}
//
///查找距给定日期最近的工作日
/// 
///如果提供的日期是一周中的指定日期,请返回该日期或继续到下一个日期
///从提供的日期向前或向后搜索。如果给定null参数,则返回最接近的工作日(即任意方向)
public static DateTime ClosestWeekDay(此DateTime日期,DayOfWeek工作日,bool includeStartDate=true,bool?searchForward=true)
{
如果(!searchForward.HasValue&&!includeStartDate)
{
抛出新ArgumentException(“如果双向搜索,则开始日期必须是有效结果”);
}
var day=date.DayOfWeek;
int add=((int)工作日-(int)天);
if(searchForward.HasValue)
{
if(添加<0&&searchForward.Value)
{
加法+=7;
}
else if(添加>0&!searchForward.Value)
{
加-=7;
}
else if(add==0&&!includeStartDate)
{
add=searchForward.Value?7:-7;
}
}
如有其他情况(添加<-3)
{
加法+=7;
}
否则,如果(添加>3)
{
加-=7;
}
返回日期。添加天数(添加);
}

@Jon Skeet回答得好

前一天:

private DateTime GetPrevWeekday(DateTime start, DayOfWeek day) {
    // The (... - 7) % 7 ensures we end up with a value in the range [0, 6]
    int daysToRemove = ((int) day - (int) start.DayOfWeek - 7) % 7;
    return start.AddDays(daysToRemove);
}

谢谢

现在是oneliner风格-以防您需要将其作为参数传递到某些机制中

DateTime.Now.AddDays(((int)yourDate.DayOfWeek - (int)DateTime.Now.DayOfWeek + 7) % 7).Day
在这种情况下:

DateTime.Now.AddDays(((int)DayOfWeek.Tuesday - (int)DateTime.Now.DayOfWeek + 7) % 7).Day
这也可能是一个扩展,这一切都取决于

public static class DateTimeExtensions
{
    public static IEnumerable<DateTime> Next(this DateTime date, DayOfWeek day)
    {
        // This loop feels expensive and useless, but the point is IEnumerable
        while(true)
        {
            if (date.DayOfWeek == day)
            {
                yield return date;
            }
            date = date.AddDays(1);
        }
    }
}
目标C版本:

+(NSInteger) daysUntilNextWeekday: (NSDate*)startDate withTargetWeekday: (NSInteger) targetWeekday
{
    NSInteger startWeekday = [[NSCalendar currentCalendar] component:NSCalendarUnitWeekday fromDate:startDate];
    return (targetWeekday - startWeekday + 7) % 7;
}

非常简单的示例要包含或排除当前日期,请指定您感兴趣的一周的日期和日期

public static class DateTimeExtensions
{
    /// <summary>
    /// Gets the next date.
    /// </summary>
    /// <param name="date">The date to inspected.</param>
    /// <param name="dayOfWeek">The day of week you want to get.</param>
    /// <param name="exclDate">if set to <c>true</c> the current date will be excluded and include next occurrence.</param>
    /// <returns></returns>
    public static DateTime GetNextDate(this DateTime date, DayOfWeek dayOfWeek, bool exclDate = true)
    {
        //note: first we need to check if the date wants to move back by date - Today, + diff might move it forward or backwards to Today
        //eg: date - Today = 0 - 1 = -1, so have to move it forward
        var diff = dayOfWeek - date.DayOfWeek;
        var ddiff = date.Date.Subtract(DateTime.Today).Days + diff;

        //note: ddiff < 0 : date calculates to past, so move forward, even if the date is really old, it will just move 7 days from date passed in
        //note: ddiff >= (exclDate ? 6 : 7) && diff < 0 : date is into the future, so calculated future weekday, based on date
        if (ddiff < 0 || ddiff >= (exclDate ? 6 : 7) && diff < 0)
            diff += 7; 

        //note: now we can get safe values between 0 - 6, especially if past dates is being used
        diff = diff % 7;

        //note: if diff is 0 and we are excluding the date passed, we will add 7 days, eg: 1 week
        diff += diff == 0 & exclDate ? 7 : 0;

        return date.AddDays(diff);
    }
}

ASP.NET是一组web技术。C#是一种语言。你真的需要用普通的.NET来考虑这个问题。现在,对于“下星期二”,是“今天之后的第一个星期二”吗?如果是周一,有人说“下周二见”,我想这意味着8天而不是1天。如果今天是星期二呢?你需要一天中的什么时间?如果今天是星期二,你想知道下星期二是什么时候?或者今天是星期一,你想找到从星期一开始的第二个星期二?这是最接近某一天的星期二。@brenjtL:如果已经是星期二了?如果已经是星期二了,那就是同一天很好的回答,如果今天是星期二(它是ha),这会在今天还是下一个星期二返回?这会在下一个星期二返回。如果您想让它今天返回,只需从第一行中删除
.AddDays(1)
,这样它也会检查
DateTime.Now
本身。哇,我只是想知道如何在下周二之前得到第n天,然后您用一个很好的示例更新了您的答案。ThanksIt很难选择正确的答案。但你的似乎是最多才多艺的,你让它很容易理解。谢谢你的帮助。@brenjt:事实上,我想说Sven's更通用,因为你可以指定一周中的哪一天,但这是你的决定:)(我现在编辑了我的,给出了一个更通用的版本。
+7)%7
解决方案非常好。虽然我没有使用它的原因是因为它有点微优化,而且太容易出错(同时也牺牲了一些可读性),当然了,imho。单元测试:[TestMethod]public void应该GetNextSaturDay(){var now=DateTime.now;var test=GetNextWeekday(DateTime.Today,DayOfWeek.Saturday);Assert.IsTrue(now.DayDayOfWeek
值交换如下:
int daysToSubtract=-((int)dateTime.DayOfWeek-(int)day+7)%7)
回答很酷,但最初的问题是关于.NET的。这是唯一一个作为DateTime扩展实现的答案。虽然其他解决方案都可以工作,但将其作为扩展方法会生成最容易使用的代码。经过一些广泛的测试后,我对原始答案做了额外的更改。这将安全地计算next天基于使用的日期、过去、现在和未来。之前的所有示例都很好,但在某些情况下失败。我没有将其作为一行语句,以便对计算结果进行补充说明。Jon Skeet的积极案例很好,尽管我的案例是从d移回1天吃了,但仍然比今天更大,如果它移动到今天或昨天…这解决了它。
DateTime.Now.AddDays(((int)DayOfWeek.Tuesday - (int)DateTime.Now.DayOfWeek + 7) % 7).Day
public static class DateTimeExtensions
{
    public static IEnumerable<DateTime> Next(this DateTime date, DayOfWeek day)
    {
        // This loop feels expensive and useless, but the point is IEnumerable
        while(true)
        {
            if (date.DayOfWeek == day)
            {
                yield return date;
            }
            date = date.AddDays(1);
        }
    }
}
    var today = DateTime.Today;
    foreach(var monday in today.Next(DayOfWeek.Monday))
    {
        Console.WriteLine(monday);
        Console.ReadKey();
    }
+(NSInteger) daysUntilNextWeekday: (NSDate*)startDate withTargetWeekday: (NSInteger) targetWeekday
{
    NSInteger startWeekday = [[NSCalendar currentCalendar] component:NSCalendarUnitWeekday fromDate:startDate];
    return (targetWeekday - startWeekday + 7) % 7;
}
public static class DateTimeExtensions
{
    /// <summary>
    /// Gets the next date.
    /// </summary>
    /// <param name="date">The date to inspected.</param>
    /// <param name="dayOfWeek">The day of week you want to get.</param>
    /// <param name="exclDate">if set to <c>true</c> the current date will be excluded and include next occurrence.</param>
    /// <returns></returns>
    public static DateTime GetNextDate(this DateTime date, DayOfWeek dayOfWeek, bool exclDate = true)
    {
        //note: first we need to check if the date wants to move back by date - Today, + diff might move it forward or backwards to Today
        //eg: date - Today = 0 - 1 = -1, so have to move it forward
        var diff = dayOfWeek - date.DayOfWeek;
        var ddiff = date.Date.Subtract(DateTime.Today).Days + diff;

        //note: ddiff < 0 : date calculates to past, so move forward, even if the date is really old, it will just move 7 days from date passed in
        //note: ddiff >= (exclDate ? 6 : 7) && diff < 0 : date is into the future, so calculated future weekday, based on date
        if (ddiff < 0 || ddiff >= (exclDate ? 6 : 7) && diff < 0)
            diff += 7; 

        //note: now we can get safe values between 0 - 6, especially if past dates is being used
        diff = diff % 7;

        //note: if diff is 0 and we are excluding the date passed, we will add 7 days, eg: 1 week
        diff += diff == 0 & exclDate ? 7 : 0;

        return date.AddDays(diff);
    }
}
[TestMethod]
    public void TestNextDate()
    {
        var date = new DateTime(2013, 7, 15);
        var start = date;
        //testing same month - forwardOnly
        Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Tuesday)); //16
        Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Wednesday)); //17
        Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Thursday)); //18
        Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Friday)); //19
        Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Saturday)); //20
        Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Sunday)); //21
        Assert.AreEqual(start.AddDays(1), date.GetNextDate(DayOfWeek.Monday)); //22

        //testing same month - include date
        Assert.AreEqual(start = date, date.GetNextDate(DayOfWeek.Monday, false)); //15
        Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Tuesday, false)); //16
        Assert.AreEqual(start.AddDays(1), date.GetNextDate(DayOfWeek.Wednesday, false)); //17

        //testing month change - forwardOnly
        date = new DateTime(2013, 7, 29);
        start = date;
        Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Tuesday)); //30
        Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Wednesday)); //31
        Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Thursday)); //2013/09/01-month increased
        Assert.AreEqual(start.AddDays(1), date.GetNextDate(DayOfWeek.Friday)); //02

        //testing year change
        date = new DateTime(2013, 12, 30);
        start = date;
        Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Tuesday)); //31
        Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Wednesday)); //2014/01/01 - year increased
        Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Thursday)); //02
    }