web-dev-qa-db-fra.com

Comment parcourir une période de temps après des jours, heures, semaines et mois en Python?

Comment puis-je répéter sur une période de temps après des jours, des heures, des semaines ou des mois?

Quelque chose comme:

for date in foo(from_date, to_date, delta=HOURS):
    print date

Où foo est une fonction, renvoyant un itérateur. J'ai regardé le module de calendrier, mais cela ne fonctionne que pour une année ou un mois spécifique, pas entre les dates.

58
sverrejoh

Utilisez dateutil et son implémentation de règle, comme ceci:

from dateutil import rrule
from datetime import datetime, timedelta

now = datetime.now()
hundredDaysLater = now + timedelta(days=100)

for dt in rrule.rrule(rrule.MONTHLY, dtstart=now, until=hundredDaysLater):
    print dt

La sortie est

2008-09-30 23:29:54
2008-10-30 23:29:54
2008-11-30 23:29:54
2008-12-30 23:29:54

Remplacez MENSUELLEMENT par ANNUELLE, MENSUELLE, HEBDOMADAIRE, QUOTIDIENNE, HORAIRE, MINUTE ou SECONDEMENT. Remplacez dtstart et until par l’objet datetime souhaité.

Cette recette a l'avantage de fonctionner dans tous les cas, y compris MENSUEL. La seule mise en garde que j'ai pu trouver est que si vous passez un nombre de jours qui n'existe pas pour tous les mois, il saute ces mois.

93

Je ne pense pas qu'il existe une méthode dans la bibliothèque Python, mais vous pouvez facilement en créer une vous-même en utilisant le module datetime :

from datetime import date, datetime, timedelta

def datespan(startDate, endDate, delta=timedelta(days=1)):
    currentDate = startDate
    while currentDate < endDate:
        yield currentDate
        currentDate += delta

Ensuite, vous pouvez l'utiliser comme ceci:

>>> for day in datespan(date(2007, 3, 30), date(2007, 4, 3), 
>>>                     delta=timedelta(days=1)):
>>>     print day
2007-03-30
2007-03-31
2007-04-01
2007-04-02

Ou, si vous souhaitez rendre votre delta plus petit:

>>> for timestamp in datespan(datetime(2007, 3, 30, 15, 30), 
>>>                           datetime(2007, 3, 30, 18, 35), 
>>>                           delta=timedelta(hours=1)):
>>>     print timestamp
2007-03-30 15:30:00
2007-03-30 16:30:00
2007-03-30 17:30:00
2007-03-30 18:30:00
41
DzinX

Pour itérer sur des mois, vous avez besoin d'une recette différente, car les timedeltas ne peuvent pas exprimer "un mois".

from datetime import date

def jump_by_month(start_date, end_date, month_step=1):
    current_date = start_date
    while current_date < end_date:
        yield current_date
        carry, new_month = divmod(current_date.month - 1 + month_step, 12)
        new_month += 1
        current_date = current_date.replace(year=current_date.year + carry,
                                            month=new_month)

(NB: vous devez soustraire 1 du mois pour l'opération module puis rajouter à new_month, depuis des mois en datetime.dates commencent à 1.)

6
giltay

J'ai réalisé cela en utilisant pandas et les bibliothèques datetime comme suit. C'était beaucoup plus pratique pour moi.

import pandas as pd
from datetime import datetime


DATE_TIME_FORMAT = '%Y-%m-%d %H:%M:%S'

start_datetime = datetime.strptime('2018-05-18 00:00:00', DATE_TIME_FORMAT)
end_datetime = datetime.strptime('2018-05-23 13:00:00', DATE_TIME_FORMAT)

timedelta_index = pd.date_range(start=start_datetime, end=end_datetime, freq='H').to_series()
for index, value in timedelta_index.iteritems():
    dt = index.to_pydatetime()
    print(dt)
2
Thilina Madumal

Approche d'itération du mois:

def months_between(date_start, date_end):
    months = []

    # Make sure start_date is smaller than end_date
    if date_start > date_end:
        tmp = date_start
        date_start = date_end
        date_end = tmp

    tmp_date = date_start
    while tmp_date.month <= date_end.month or tmp_date.year < date_end.year:
        months.append(tmp_date)  # Here you could do for example: months.append(datetime.datetime.strftime(tmp_date, "%b '%y"))

        if tmp_date.month == 12: # New year
            tmp_date = datetime.date(tmp_date.year + 1, 1, 1)
        else:
            tmp_date = datetime.date(tmp_date.year, tmp_date.month + 1, 1)
    return months

Plus de code mais il fera très bien face à de longues périodes de temps en vérifiant que les dates données sont en ordre ...

0
Rafa He So