Подтвердить что ты не робот

Как проверить, находится ли текущее время в диапазоне в python?

Мне нужно проверить, находится ли текущее время в таймере. Самый простой случай time_end > time_start:

if time(6,0) <= now.time() <= time(12,00): print '1'

Но проблемы начинаются, когда пользователь вводит временной диапазон, когда время окончания меньше, чем время начала, например. "23:00 - 06:00". Время, подобное "00: 00", будет в этом диапазоне. Около 5 лет назад я написал эту функцию PHP:

function checkInterval($start, $end)
  {    
    $dt = date("H:i:s");    

    $tstart = explode(":", $start);
    $tend =   explode(":", $end);
    $tnow =   explode(":", $dt);

    if (!$tstart[2])
      $tstart[2] = 0;

    if (!$tend[2])
      $tend[2] = 0;  

    $tstart = $tstart[0]*60*60 + $tstart[1]*60 + $tstart[2];
    $tend   = $tend[0]*60*60   + $tend[1]*60   + $tend[2];
    $tnow   = $tnow[0]*60*60   + $tnow[1]*60   + $tnow[2];

    if ($tend < $tstart)
      {
        if ($tend - $tnow > 0 && $tnow > $tstart)
          return true;
        else if ($tnow - $tstart > 0 && $tnow > $tend)
          return true;
        else if ($tend > $tnow && $tend < $tstart && $tstart > $tnow)
          return true;
        else return false;
      } else
      {
        if ($tstart < $tnow && $tend > $tnow)
          return true;
        else
          return false;
      }

Теперь мне нужно сделать то же самое, но я хочу сделать это красивым. Итак, какой алгоритм я должен использовать, чтобы определить, находится ли текущее время "00: 00" в обратном диапазоне, например. ['23:00', '01:00']?

4b9b3361

Ответ 1

Решение Python будет намного короче.

def time_in_range(start, end, x):
    """Return true if x is in the range [start, end]"""
    if start <= end:
        return start <= x <= end
    else:
        return start <= x or x <= end

Используйте класс datetime.time для start, end и x.

>>> import datetime
>>> start = datetime.time(23, 0, 0)
>>> end = datetime.time(1, 0, 0)
>>> time_in_range(start, end, datetime.time(23, 30, 0))
True
>>> time_in_range(start, end, datetime.time(12, 30, 0))
False

Ответ 2

Дата/время сложнее, чем вы думаете

Расчеты, связанные с датой/временем, могут быть очень сложными, потому что вы должны учитывать часовой пояс, високосные годы, летнее время и множество angular случаев. Существует поучительное видео из выступления Таави Бернса на PyCon2012, озаглавленное "Что нужно знать о времени":

Что нужно знать о сроках:
time, datetime и calendar из стандартной библиотеки немного запутаны. Узнайте, что использовать, где и как (особенно, когда у вас есть пользователи во многих часовых поясах), и какие дополнительные модули вы можете посмотреть.

Event: PyCon US 2012/Speakers: Taavi Burns/Recorded: March 10, 2012

Используйте дату/время с учетом часового пояса для расчетов

Концепция datetime.time на завтра недействительна, потому что datetime.time не имеет никакой информации о дате. Вы, вероятно, хотите преобразовать все в информацию о часовом поясе datetime.datetime перед сравнением:

def time_in_range(start, end, x):
    today = timezone.localtime().date()
    start = timezone.make_aware(datetime.datetime.combine(today, start))
    end = timezone.make_aware(datetime.datetime.combine(today, end))
    x = timezone.make_aware(datetime.datetime.combine(today, x))
    if end <= start:
        end += datetime.timedelta(days=1) # tomorrow!
    if x <= start
        x += datetime.timedelta(days=1) # tomorrow!
    return start <= x <= end