How to iterate over time for several days, hours, weeks, and months in Python?

How can I iterate over a period of time by days, hours, weeks, or months?

Something like:

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

Where foo is a function that returns an iterator. I looked at the calendar module, but this only works for one year or month, and not between dates.

+50
python datetime
Sep 30 '08 at 15:35
source share
7 answers

Use dateutil and its rrule implementation, for example:

 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 

Exit

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

Replace MONTHLY OF ANY YEARS, MONTHLY, WEEKLY, DAILY, HOURS, MINUTES, OR SECOND. Replace dtstart until you want to use any datetime object.

This recipe has the advantage of working in all cases, including MONTHLY. The only caveat I can find is that if you miss a day number that does not exist for all months, it skips those months.

+82
Sep 30 '08 at 21:30
source share

I don't think there is a method in the Python library, but you can easily create it yourself using the datetime module:

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

Then you can use it as follows:

 >>> 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 

Or if you want to reduce your delta:

 >>> 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 
+38
Sep 30 '08 at 15:50
source share

To repeat several months, you need a different recipe, because timedeltas cannot express "one month".

 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: you have to subtract 1 from the month for the module operation, and then add it back to new_month , since the months in datetime.date start at 1.)

+6
Sep 30 '08 at 17:14
source share

Monthly iterative approach:

 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 

More code, but it will do a great job with long periods of time by checking that the date data is ok ...

0
Sep 13 '16 at 13:22
source share

I achieved this using the pandas and datetime libraries as follows. It was much more convenient for me.

 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) 
0
May 23 '18 at 9:34
source share

This library provides a handy calendar tool: mxDateTime , that should be enough :)

-one
Sep 30 '08 at 15:43
source share

You must change this line to make this work correctly:

current_date = current_date.replace (year = current_date.year + carry, month = new_month, day = 1)

;)

-2
Apr 15 '09 at 13:04
source share



All Articles