Получите время, оставшееся до воскресенья 9:30 вечера - PullRequest
1 голос
/ 24 апреля 2019

То, что я хочу сделать, в основном в названии вопроса.

Это то, что я до сих пор пытался безуспешно.

Обратите внимание, что я не реализовал точные часы и минутыпока (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;

Если возможно, я бы также хотел использовать Paris TimeZone.

Ответы [ 2 ]

1 голос
/ 24 апреля 2019

Вот пример использования Noda Time, включая обработку часового пояса. Он не пытается справиться с «интересными» ситуациями, когда (скажем) вы просите о следующем 1:30 утра, а уже 1:45 утра, но часы возвращаются в 2 часа ночи - в этом случае правильный ответ действительно «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;
    }
}
1 голос
/ 24 апреля 2019

Мне кажется, что вся арифметика 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...