Алгоритм проверки того, попадает ли определенный час в данный период времени - PullRequest
2 голосов
/ 01 марта 2010

Предположим, у меня есть часы начала и окончания, в которые должна выполняться некоторая обработка:

начало 20:00 Конец 07: 00

Теперь какой алгоритм лучше всего проверить, попадает ли определенное значение времени DateTime в этот диапазон? Заранее спасибо!

Обратите внимание, что время начала и окончания, указанное выше, указывает на то, что мы имеем дело с «работой на ночь». Это означает, что проверяемый период начинается в 20:00 вечера и заканчивается в 07:00 следующего утра.

Ответы [ 10 ]

6 голосов
/ 01 марта 2010

Предположим, у вас есть только время, а не дата.

if end_time >= start_time:
    return start_time <= current_time <= end_time
else:
    return start_time <= current_time or current_time <= end_time
3 голосов
/ 01 марта 2010

Если вы уверены, что это в тот же день

вам, похоже, тоже не до секунды

Преобразование всего за минуты

startminute = 20 * 60 + 0
endminute = 7 * 60 + 0
eventminute = x * 60 + y // with event having the form xx:yy
return startminute < eventminute && eventminute < endminute 

Другой вариант - получить 3 раза в формате DateTime

DateTime start, end, event

return (start < event && event < end);
1 голос
/ 01 марта 2010

Если у вас есть начало, конец и теперь DateTime, вы можете использовать

bool within = start.TimeOfDay.TotalHours <= now.TimeOfDay.TotalHours && 
              now.TimeOfDay.TotalHours <= end.TimeOfDay.TotalHours;
0 голосов
/ 01 марта 2010

Посчитайте все время в единицах минут, начиная со дня старта.

struct DateTime {
  uint_8 hour_;
  uint_8 minute_;
};

bool
isTimeWithin( DateTime start, DataTime stop, DateTime query ) {

  // The following times are counted from the beginning of start day

  uint_16 startInMins = (60 * start.hour_ + start.minute_);

  // Added 24*60 since "stop" is always "overnight" from "start"
  uint_16 stopInMins = 24 * 60 + (60 * stop.hour_ + stop.minute_); 

  // The ternary operator checks whether "query" is in the same day as
  // "start" or the next day
  uint_16 queryInMins = (query.hour_ < start.hour_ ? 24 * 60 : 0 ) + 
                           (60 * query.hour_ + query.minute_); 

  return ((startInMins <= queryInMins) && (queryInMins <= stopInMins));

}

РЕДАКТИРОВАТЬ: Улучшено форматирование.

0 голосов
/ 01 марта 2010

Используйте метод TimeOfDay:

DateTime dtStart = new DateTime(0,0,0,20,0,0);
DateTime dtEnd = new DateTime(0,0,0,7,0,0);

if (DateTime.Now.TimeOfDay < dtEnd.TimeOfDay || DateTime.Now.TimeOfDay > dtStart.TimeOfDay)
{
    // your code here
}
0 голосов
/ 01 марта 2010
// initializing with some sample values
TimeSpan start = TimeSpan.FromHours(20);
TimeSpan end = TimeSpan.FromHours(7);
DateTime now = DateTime.Now.TimeOfDay;

return start<end
    ? start <= now.TotalHours && now.TotalHours <= end
    : start <= now.TotalHours || now.TotalHours <= end;
0 голосов
/ 01 марта 2010

С окном overnight я не думаю, что можно сделать что-то особенно умное, кроме прямой проверки ваших DateTime TimeOfDay на границах:

using System;

namespace Question2355777
{
    class Program
    {    
        private static bool IsInOvernightWindow(
            DateTime dateTimeUnderTest, 
            TimeSpan morningEnd, 
            TimeSpan eveningStart)
        {
            TimeSpan timeOfDay = dateTimeUnderTest.TimeOfDay;
            return timeOfDay <= morningEnd || timeOfDay >= eveningStart;
        }

        static void Main(string[] args)
        {
            TimeSpan eveningStart = TimeSpan.FromHours(20);
            TimeSpan morningEnd = TimeSpan.FromHours(7);

            Console.WriteLine("{0} {1}", 
                DateTime.Today.AddHours(3),
                IsInOvernightWindow(
                    DateTime.Today.AddHours(3), 
                    morningEnd, 
                    eveningStart));

            Console.WriteLine("{0} {1}", 
                DateTime.Today.AddHours(12),
                IsInOvernightWindow(
                    DateTime.Today.AddHours(12), 
                    morningEnd, 
                    eveningStart));

            Console.WriteLine("{0} {1}", 
                DateTime.Today.AddHours(21),
                IsInOvernightWindow(
                    DateTime.Today.AddHours(21), 
                    morningEnd, 
                    eveningStart));

            Console.ReadLine();
        }
    }
}

производит

01/03/2010 03:00:00 True
01/03/2010 12:00:00 False
01/03/2010 21:00:00 True
0 голосов
/ 01 марта 2010

если у вас есть ВСЕ значения для запуска и остановки, разве у вас нет пустого набора?

Игнорировать очевидное предположение - начальный день X, конечный день X + Y.

[править]
так как вопрос был отредактирован, так и будет ответ ....
для времени начала, времени окончания и времени теста получите количество миллисекунд с начала эпохи
(определите это так, как вам нравится)
а затем проверьте, является ли тест> = start и <= end <br> [/ Править]

0 голосов
/ 01 марта 2010

Я думаю, что c # поддерживает больше, чем / меньше, чем операторы для переменных DateTime, так что просто скажем

if ((beginDateTime<myDateTime)&&(myDateTime<endDateTime))
{
    ...
}

Поддерживается также больше или равно и меньше или равно.

0 голосов
/ 01 марта 2010

Не зная, как это сделать в C #, я бы пошел с преобразованием времени начала и окончания во временную метку, а затем провел бы простое сравнение if (end time >= given time AND start time <= given time). Может быть, это поможет вам начать или подскажет, что искать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...