生成一个时间间隔之间的date时间列表

给定两个date时间( start_dateend_date ),我想生成这两个date之间的其他date时间的列表,新的date时间是由一个可变的时间间隔。 例如2011-10-10和2011-12-12之间的每4天,或者从现在到明天19点之间的每8小时。

也许大约相当于Dateperiod PHP类的东西。

在Python中完成这个操作的最有效的方法是什么?

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

适用于date和date时间对象。 你的第二个例子:

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

尝试这个:

 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 

问题中的例子“从现在到明天19:00之间的每8小时”将会这样写:

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

请注意, period的有效值是为relativedelta相对信息定义的值,即: 'years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds', 'microseconds'

我的解决scheme按照问题的要求返回一个列表 。 如果你不需要所有的元素,你可以使用生成器,就像在@MartijnPieters的答案。

我真的很喜欢@Martijn Pieters和@ÓscarLópez的答案。 让我build议我在这两个答案之间的综合解决scheme。

 from datetime import date, datetime, timedelta def datetime_range(start, end, delta): current = start if not isinstance(delta, timedelta): delta = timedelta(**delta) while current < end: yield current current += delta start = datetime(2015,1,1) end = datetime(2015,1,31) #this unlocks the following interface: for dt in datetime_range(start, end, {'days': 2, 'hours':12}): print dt print dt 2015-01-01 00:00:00 2015-01-03 12:00:00 2015-01-06 00:00:00 2015-01-08 12:00:00 2015-01-11 00:00:00 2015-01-13 12:00:00 2015-01-16 00:00:00 2015-01-18 12:00:00 2015-01-21 00:00:00 2015-01-23 12:00:00 2015-01-26 00:00:00 2015-01-28 12:00:00