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?
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, …
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 ...
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With