web-dev-qa-db-fra.com

Comment vérifier si l'heure actuelle est à portée en python?

J'ai besoin de vérifier si l'heure actuelle est dans timerange. Le cas le plus simple time_end> time_start:

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

Mais les problèmes commencent lorsque l'utilisateur entre dans une plage de temps lorsque l'heure de fin est inférieure à l'heure de début, par ex. "23h00 - 06h00". Une heure comme '00: 00 'sera dans cette plage. Il y a environ 5 ans, j'ai écrit ceci 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;
      }

Maintenant, je dois faire la même chose, mais je veux que ça soit beau. Alors, quel algorithme dois-je utiliser pour déterminer si l'heure actuelle '00: 00 'est dans la plage inversée par exemple ['23:00', '01:00']?

23
night-crawler

La solution Python va être beaucoup, beaucoup plus courte.

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

Utilisez le datetime.time classe pour start, end et 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
41
Dietrich Epp

La date et l'heure sont plus délicates que vous ne le pensez

Les calculs impliquant la date/l'heure peuvent être très difficiles car vous devez prendre en compte le fuseau horaire, les années bissextiles, l'heure d'été et de nombreux cas d'angle. Il y a une vidéo éclairante de la conférence de Taavi Burns à PyCon2012 intitulée "Ce que vous devez savoir sur les horaires":

Ce que vous devez savoir sur les horaires :
time, datetime et calendar de la bibliothèque standard sont un peu compliqués. Découvrez: quoi utiliser où et comment (en particulier lorsque vous avez des utilisateurs dans de nombreux fuseaux horaires), et quels modules supplémentaires vous voudrez peut-être examiner.

Événement : PyCon US 2012/ Haut-parleurs : Taavi Burns/ Enregistré : 10 mars 2012

Utiliser le datetime sensible au fuseau horaire pour les calculs

Le concept d'un datetime.time car demain est nul, car datetime.time manque d'informations sur la date. Vous voulez probablement tout convertir en fonction du fuseau horaire datetime.datetime avant de comparer:

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
8
Paulo Scardine