Как проверить, существует ли DateTime.Now между двумя данными DateTimes только для временной части?

Для моего приложения мне нужно знать, находится ли Now() между двумя значениями.

Пользователь может установить время начала и окончания, чтобы он не нарушил уведомление (например, ночью).

Итак, если у вас есть два TimePicker (начало и конец), которые пользователь может установить.

Допустим, пользователь устанавливает 22:00 для StartTime и 07:00 для EndTime (это будет охватывать ночь).

Как проверить, находится ли DateTime.Now между выбранным временем запуска и окончания?

EDIT: Я только хочу, чтобы это работало с Часом и минутной частью. Поэтому, если пользователь устанавливает время начала и окончания, это должно работать каждую ночь.

Ответы

Ответ 1

Сначала вам нужно преобразовать все в одни и те же единицы (мы будем использовать TimeSpan), тогда вам нужно посмотреть, переходят ли время начала в полночь, и, наконец, сделайте свое сравнение на основе результатов этой проверки:

// convert everything to TimeSpan
TimeSpan start = new TimeSpan(22, 0, 0);
TimeSpan end = new TimeSpan(07, 0, 0);
TimeSpan now = DateTime.Now.TimeOfDay;
// see if start comes before end
if (start < end)
    return start <= now && now <= end;
// start is after end, so do the inverse comparison
return !(end < now && now < start);

Здесь функция, которая сделает это для вас:

bool TimeBetween(DateTime datetime, TimeSpan start, TimeSpan end)
{
    // convert datetime to a TimeSpan
    TimeSpan now = datetime.TimeOfDay;
    // see if start comes before end
    if (start < end)
        return start <= now && now <= end;
    // start is after end, so do the inverse comparison
    return !(end < now && now < start);
}

Вы бы назвали это так:

bool silenceAlarm = TimeBetween(DateTime.Now, StartTime.Value, EndTime.Value);

Ответ 2

Поскольку вы собираете только два раза без дат, вам нужно выяснить, есть ли два раза с того же дня или нет. Если вы поместите StartTime, EndTime и Now в TimeSpans:

if (StartTime > EndTime) 
{
    // the range crosses midnight, do the comparisons independently
    return (StartTime < Now) || (Now < EndTime);
}
else 
{
    // the range is on the same day, both comparisons must be true
    return StartTime < Now && Now < EndTime;
}

Ответ 3

    public static bool isCurrenctDateBetween(DateTime fromDate, DateTime toDate)
    {
        DateTime curent = DateTime.Now.Date;
        if (fromDate.CompareTo(toDate) >= 1)
        {
            MessageBox.Show("From Date shouldn't be grater than To Date", "DateRange",MessageBoxButton.OKCancel, MessageBoxImage.Warning);
        }
        int cd_fd = curent.CompareTo(fromDate);
        int cd_td = curent.CompareTo(toDate);

        if (cd_fd == 0 || cd_td == 0)
        {
            return true;
        }

        if (cd_fd >= 1 && cd_td <= -1)
        {
            return true;
        }
        return false;
    }

Ответ 4

DateTime nowDate = DateTime.Now;
// set these to today + time from time picker
DateTime startDate = new DateTime(nowDate.Year, nowDate.Month, nowDate.Day,
    selectedStart.Hour, selectedStart.Minute, 0);
DateTime endDate = new DateTime(nowDate.Year, nowDate.Month, nowDate.Day, 
    selectedEnd.Hour, selectedEnd.Minute, 0);
bool isBetween = nowDate < endDate && nowDate > startDate;

Обновление 08-Jun-2016
Не уверен, почему нисходящее направление было подходящим, так как это рабочее решение. ОП задал специально для DateTime, однако я рекомендую использовать TimeSpan вместо этого в соответствии с ответом @Gabe.

Вот работая по моему ответу:

public static bool TimeBetween(DateTime check, DateTime start, DateTime end, bool inclusive = true)
{
    var from = new DateTime(check.Year, check.Month, check.Day, 
        start.Hour, start.Minute, start.Second, start.Millisecond);
    var to = new DateTime(check.Year, check.Month, check.Day, 
        end.Hour, end.Minute, end.Second, end.Millisecond);

    if (inclusive)
        return from <= check && to >= check;

    return from < check && to > check;
}

Здесь работает скрипка: https://dotnetfiddle.net/vZCXqv.

Полный код:

using System;

public class Program
{
    public static void Main()
    {
        var start = new DateTime(1, 1, 1, 9, 0, 0);
        var end = new DateTime(1, 1, 1, 17, 0, 0);

        Console.WriteLine("{0} - Too early",                TimeBetween(new DateTime(2014, 1, 1, 08, 59, 59, 999), start, end));
        Console.WriteLine("{0} - On start time exclusive",  TimeBetween(new DateTime(2014, 1, 1, 09, 00, 00, 000), start, end, false));
        Console.WriteLine("{0} - On start time inclusive",  TimeBetween(new DateTime(2014, 1, 1, 09, 00, 00, 000), start, end));
        Console.WriteLine("{0} - After start time",         TimeBetween(new DateTime(2014, 1, 1, 09, 00, 00, 001), start, end));        
        Console.WriteLine("{0} - Before end time",          TimeBetween(new DateTime(2014, 1, 1, 16, 59, 59, 999), start, end));
        Console.WriteLine("{0} - On end time inclusive",    TimeBetween(new DateTime(2014, 1, 1, 17, 00, 00, 000), start, end));
        Console.WriteLine("{0} - On end time exclusive",    TimeBetween(new DateTime(2014, 1, 1, 17, 00, 00, 000), start, end, false));
        Console.WriteLine("{0} - Too late",                 TimeBetween(new DateTime(2014, 1, 1, 17, 00, 00, 001), start, end));
    }

    public static bool TimeBetween(DateTime check, DateTime start, DateTime end, bool inclusive = true)
    {
        var from = new DateTime(check.Year, check.Month, check.Day, start.Hour, start.Minute, start.Second, start.Millisecond);
        var to = new DateTime(check.Year, check.Month, check.Day, end.Hour, end.Minute, end.Second, end.Millisecond);

        if (inclusive)
            return from <= check && to >= check;

        return from < check && to > check;
    }
}

Ответ 5

Dupe Найти, если текущее время падает во временном диапазоне

DateTime start = new DateTime(2009, 12, 9, 10, 0, 0));
DateTime end = new DateTime(2009, 12, 10, 12, 0, 0));
DateTime now = DateTime.Now;

if ((now > start) && (now < end))
{
   //match found
}

Временной интервал, опять же, взятый из обмана.

TimeSpan start = new TimeSpan(10, 0, 0);
TimeSpan end = new TimeSpan(12, 0, 0);
TimeSpan now = DateTime.Now.TimeOfDay;

if ((now > start) && (now < end))
{
   //match found
}

Ответ 6

Я использую это, поэтому вы можете передавать DateTime напрямую:

        public static bool TimeBetween(DateTime time, DateTime startDateTime, DateTime endDateTime)
    {
        // get TimeSpan
        TimeSpan start = new TimeSpan(startDateTime.Hour, startDateTime.Minute, 0);
        TimeSpan end = new TimeSpan(endDateTime.Hour, endDateTime.Minute, 0);

        // convert datetime to a TimeSpan
        TimeSpan now = time.TimeOfDay;
        // see if start comes before end
        if (start < end)
            return start <= now && now <= end;
        // start is after end, so do the inverse comparison
        return !(end < now && now < start);
    }

Ответ 7

Просто сделайте прямое сравнение.

if (date > startdate & date < enddate)