132 votes

Comment arrondir la minute d'un objet datetime ?

J'ai un datetime produit à l'aide de strptime() .

>>> tm
datetime.datetime(2010, 6, 10, 3, 56, 23)

Ce que je dois faire, c'est arrondir la minute à la 10e minute la plus proche. Ce que j'ai fait jusqu'à présent, c'est prendre la valeur de la minute et utiliser la fonction round().

min = round(tm.minute, -1)

Cependant, comme dans l'exemple ci-dessus, il donne une heure non valide lorsque la valeur des minutes est supérieure à 56, c'est-à-dire : 3:60

Quelle est la meilleure façon de procéder ? Est-ce que datetime soutenir cela ?

3 votes

Aujourd'hui, timestamp a une méthode floor(...) .

168voto

Omnifarious Points 25666

Cela permettra d'obtenir le "plancher" d'un datetime objet stocké dans tm arrondi à la marque de 10 minutes avant que tm .

tm = tm - datetime.timedelta(minutes=tm.minute % 10,
                             seconds=tm.second,
                             microseconds=tm.microsecond)

Si vous voulez un arrondi classique à la dizaine de minutes la plus proche, faites ceci :

discard = datetime.timedelta(minutes=tm.minute % 10,
                             seconds=tm.second,
                             microseconds=tm.microsecond)
tm -= discard
if discard >= datetime.timedelta(minutes=5):
    tm += datetime.timedelta(minutes=10)

ou ceci :

tm += datetime.timedelta(minutes=5)
tm -= datetime.timedelta(minutes=tm.minute % 10,
                         seconds=tm.second,
                         microseconds=tm.microsecond)

115voto

Le Droid Points 455

Fonction générale pour arrondir une date à n'importe quel laps de temps en secondes :

def roundTime(dt=None, roundTo=60):
   """Round a datetime object to any time lapse in seconds
   dt : datetime.datetime object, default now.
   roundTo : Closest number of seconds to round to, default 1 minute.
   Author: Thierry Husson 2012 - Use it as you want but don't blame me.
   """
   if dt == None : dt = datetime.datetime.now()
   seconds = (dt.replace(tzinfo=None) - dt.min).seconds
   rounding = (seconds+roundTo/2) // roundTo * roundTo
   return dt + datetime.timedelta(0,rounding-seconds,-dt.microsecond)

Échantillons arrondis à 1 heure et à 30 minutes :

print roundTime(datetime.datetime(2012,12,31,23,44,59,1234),roundTo=60*60)
2013-01-01 00:00:00

print roundTime(datetime.datetime(2012,12,31,23,44,59,1234),roundTo=30*60)
2012-12-31 23:30:00

16 votes

Malheureusement, cela ne fonctionne pas avec les temps de date qui tiennent compte du tz. Il faut utiliser dt.replace(hour=0, minute=0, second=0) au lieu de dt.min .

4 votes

@skoval00 + druska J'ai suivi vos conseils pour prendre en charge le temps de la date qui tient compte de TZ. Merci !

0 votes

Merci @skoval00 - il m'a fallu un certain temps pour comprendre pourquoi la fonction ne fonctionnait pas avec mes données.

3voto

mykhal Points 5873

Si vous ne voulez pas utiliser la condition, vous pouvez utiliser modulo opérateur :

minutes = int(round(tm.minute, -1)) % 60

UPDATE

Vous vouliez quelque chose comme ça ?

def timeround10(dt):
    a, b = divmod(round(dt.minute, -1), 60)
    return '%i:%02i' % ((dt.hour + a) % 24, b)

timeround10(datetime.datetime(2010, 1, 1, 0, 56, 0)) # 0:56
# -> 1:00

timeround10(datetime.datetime(2010, 1, 1, 23, 56, 0)) # 23:56
# -> 0:00

si vous voulez un résultat sous forme de chaîne de caractères. Pour obtenir un résultat sous forme de date, il est préférable d'utiliser timedelta - voir les autres réponses ;)

0 votes

Ah mais le problème ici est que l'heure doit aussi augmenter.

1 votes

@Lucas Manco - Ma solution fonctionne également très bien et je pense qu'elle est plus logique.

0voto

Leniel Macaferi Points 38324

Cela peut vous donner une idée pour vous y rendre :

http://www.daniweb.com/forums/thread276921.html

-2voto

Sedorner Points 3309

J'ai également trouvé ceci en cherchant une solution similaire : round_off

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X