预留时间直到星期日晚上9:30

时间:2019-04-24 05:01:00

标签: c# datetime

我想做的基本上是在问题标题中。

这是我到目前为止尝试过的,但是没有成功。

请注意,我尚未实施确切的小时和分钟(晚上9:30)。

出于某种原因,实际上似乎总是返回00:00:59到00:00:01之间的值

DateTime nextSunday = DateTime.Today.AddDays(((int)DayOfWeek.Sunday - (int)DateTime.Today.DayOfWeek + 7) % 7) + new TimeSpan(21, 30, 0);
TimeSpan untilNextSunday = nextSunday - DateTime.Now;

await ReplyAsync($"It is in **{TimeSpan.FromSeconds(untilNextSunday.Seconds)}**");

等于

var today = DateTime.Today;
var daysUntilSunday = ((int)DayOfWeek.Sunday - (int)today.DayOfWeek + 7) % 7;
var nextSunday = today.AddDays(daysUntilSunday);
var ts = new TimeSpan(21, 30, 0);
nextSunday = nextSunday.Date + ts;

TimeSpan untilNextSunday = nextSunday - DateTime.Now;

如果可能的话,我也想使用巴黎时区。

2 个答案:

答案 0 :(得分:1)

我倾向于发现所有DateTime.Today.AddDays(((int)DayOfWeek.Sunday - (int)DateTime.Today.DayOfWeek + 7) % 7) + new TimeSpan(21, 30, 0)算术都很混乱。取而代之的是,我尝试采用一种更迭代的方法,该方法可以明确地加以解释。

尝试一下:

public static DateTime GetNextDateTime(DateTime now, DayOfWeek targetDay, TimeSpan targetTime)
{
    DateTime target = now.Date.Add(targetTime);

    while (target < now || target.DayOfWeek != targetDay)
    {
        target = target.AddDays(1.0);
    }

    return target;
}

现在您可以像这样使用它:

DateTime now = DateTime.Now;
DateTime target = GetNextDateTime(DateTime.Now, DayOfWeek.Sunday, new TimeSpan(21, 30, 0));
TimeSpan untilNextSunday = target.Subtract(now);

答案 1 :(得分:1)

这是使用Noda Time的示例,包括时区处理。它不会尝试处理“有趣”的情况,例如(您)要求下一个1:30 am,而现在已经是1:45 am,但是时钟会回到2am-在这种情况下,正确的答案实际上是“ 45分钟”但是这段代码会给你一个星期。

using System;
using NodaTime;

class Test
{
    static void Main()
    {
        var duration = GetDurationToNext(
            IsoDayOfWeek.Sunday, new LocalTime(21, 30),
            DateTimeZoneProviders.Tzdb["Europe/Paris"],
            SystemClock.Instance);

        Console.WriteLine($"Duration: {duration}");
    }

    static Duration GetDurationToNext(
        IsoDayOfWeek dayOfWeek,
        LocalTime timeOfDay,
        DateTimeZone zone,
        IClock clock) // Or just take an instant
    {
        var now = clock.GetCurrentInstant();
        var localNow = now.InZone(zone).LocalDateTime;

        var localNext = localNow
            .Date.With(DateAdjusters.NextOrSame(dayOfWeek))
            .At(timeOfDay);
        // Handle "we're already on the right day-of-week, but
        // later in the day"
        if (localNext <= localNow)
        {
            localNext = localNext.PlusWeeks(1);
        }

        var zonedNext = localNext.InZoneLeniently(zone);
        var instantNext = zonedNext.ToInstant();
        return instantNext - now;
    }
}