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.
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.
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
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.date
s commencent à 1.)
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)
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 ...