Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate a list of datetimes between an interval

Given two datetimes (start_date and end_date), I'd like to generate a list of other datetimes between these two dates, the new datetimes being separated by a variable interval. e.g. every 4 days between 2011-10-10 and 2011-12-12 or every 8 hours between now and tomorrow 19p.m.

Maybe something roughly equivalent to the Dateperiod PHP class.

What would be the most efficient way to accomplish this in Python?

like image 705
Joucks Avatar asked May 21 '12 15:05

Joucks


People also ask

How do I print the months between two dates in Python?

date(2020, 1, 1) today = datetime. date. today() for month in months_between(start_of_2020, today): print(month. strftime("%B %Y")) # January 2020, February 2020, March 2020, …

How do I get a list of months in Python?

months is defined with the lines months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', and 'August', 'September', 'October', 'November', 'December'] (note that a \ could also be used to split a long line, but that is not necessary in this case because Python is intelligent enough to recognize that ...


2 Answers

Use datetime.timedelta:

from datetime import date, datetime, timedelta  def perdelta(start, end, delta):     curr = start     while curr < end:         yield curr         curr += delta  >>> for result in perdelta(date(2011, 10, 10), date(2011, 12, 12), timedelta(days=4)): ...     print result ... 2011-10-10 2011-10-14 2011-10-18 2011-10-22 2011-10-26 2011-10-30 2011-11-03 2011-11-07 2011-11-11 2011-11-15 2011-11-19 2011-11-23 2011-11-27 2011-12-01 2011-12-05 2011-12-09 

Works for both dates and datetime objects. Your second example:

>>> for result in perdelta(datetime.now(), ...         datetime.now().replace(hour=19) + timedelta(days=1), ...         timedelta(hours=8)): ...     print result ...  2012-05-21 17:25:47.668022 2012-05-22 01:25:47.668022 2012-05-22 09:25:47.668022 2012-05-22 17:25:47.668022 
like image 109
Martijn Pieters Avatar answered Oct 07 '22 16:10

Martijn Pieters


Try this:

from datetime import datetime from dateutil.relativedelta import relativedelta  def date_range(start_date, end_date, increment, period):     result = []     nxt = start_date     delta = relativedelta(**{period:increment})     while nxt <= end_date:         result.append(nxt)         nxt += delta     return result 

The example in the question, "every 8 hours between now and tomorrow 19:00" would be written like this:

start_date = datetime.now() end_date = start_date + relativedelta(days=1) end_date = end_date.replace(hour=19, minute=0, second=0, microsecond=0) date_range(start_date, end_date, 8, 'hours')     

Notice that the valid values for period are those defined for the relativedelta relative information, namely: 'years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds', 'microseconds'.

My solution returns a list, as required in the question. If you don't need all the elements at once you can use generators, as in @MartijnPieters answer.

like image 23
Óscar López Avatar answered Oct 07 '22 16:10

Óscar López