如何使用python dateutils在某个日期之前创建日期范围?

时间:2016-01-22 14:29:14

标签: python date datetime python-dateutil

我正在尝试获取给定范围内的月份列表。具体来说,根据范围2015-12-31 - 2016-01-01,我想获取列表2015-122016-01

我正在使用dateutil的rrule,但until参数并没有真正帮助,因为它似乎正在寻找完整的月份。

E.g:

from dateutil.relativedelta import relativedelta
from dateutil.rrule import rrule, MONTHLY

list(rrule(MONTHLY, dtstart=datetime(2015, 12, 31), until=datetime(2016,01,01)))

这只返回[datetime.datetime(2015, 12, 31, 0, 0)],而不是[datetime.datetime(2015, 12, 31, 0, 0), datetime.datetime(2016, 01, 01, 0, 0)]

同样,我希望12月的任何开始日和1月的任何结束日都有相同的输出。也就是说,我只关心月份为2015-122016-01的事实。对我来说,日期部分并不重要,但我每月只需要一个datetime(这些输入最多为2个,day组件的值为。)

有一个简单的解决方案,还是我必须增加DAILY并建立我自己的几个月?

4 个答案:

答案 0 :(得分:3)

list(rrule(MONTHLY, dtstart=datetime(2015, 12, 31), until=datetime(2016,01,01))) 1月份未返回1月的原因是因为12月31日至1月1日之间没有一个月(基于MONTHLY参数)。

由于您不需要日期组件,我将执行一些日期操作:

def date_list(start, end):
    start = datetime.date(start.year, start.month, 1)
    end = datetime.date(end.year, end.month, 1)
    dates = [dt for dt in rrule(MONTHLY, dtstart=start, until=end)]
    return dates

这样做是接受任何开始和结束日期,然后将这两个日期重置为本月的第一天。这可确保存在整月。它将返回一个日期列表,每个日期将是该月的第一天。

例如,使用您的输入

>>> print date_list(datetime.date(2015,12,28), datetime.date(2016,1,1))
[datetime.datetime(2015, 12, 1, 0, 0), datetime.datetime(2016, 1, 1, 0, 0)]

同月:

>>> print date_list(datetime.date(2015,12,28), datetime.date(2015,12,31))
[datetime.datetime(2015, 12, 1, 0, 0)]

无效范围(开始前结束):

>>> print date_list(datetime.date(2015,12,28), datetime.date(2015,11,30))
[]

范围更广:

>>> print date_list(datetime.date(2015,12,28), datetime.date(2016,8,3))
[datetime.datetime(2015, 12, 1, 0, 0), 
datetime.datetime(2016, 1, 1, 0, 0), 
datetime.datetime(2016, 2, 1, 0, 0), 
datetime.datetime(2016, 3, 1, 0, 0), 
datetime.datetime(2016, 4, 1, 0, 0), 
datetime.datetime(2016, 5, 1, 0, 0), 
datetime.datetime(2016, 6, 1, 0, 0), 
datetime.datetime(2016, 7, 1, 0, 0), 
datetime.datetime(2016, 8, 1, 0, 0)]

答案 1 :(得分:1)

我已经使用套装完成了它:

months = set()

for dt in rrule(DAILY, dtstart=start_date, until=end_date):
    months.add(dt.strftime('%Y-%m-.*'))

答案 2 :(得分:0)

认为你必须进行某种迭代。例如,使用deltas,以下方法将起到作用:

import datetime

start = datetime.datetime(2015, 12, 31)
stop = datetime.datetime(2016, 1, 8)

delta = stop - start

answer = [start+datetime.timedelta(days=idx) for idx in range(delta.days+1)]
print(answer)

<强>输出

[datetime.datetime(2015, 12, 31, 0, 0),
 datetime.datetime(2016, 1, 1, 0, 0),
 datetime.datetime(2016, 1, 2, 0, 0),
 datetime.datetime(2016, 1, 3, 0, 0),
 datetime.datetime(2016, 1, 4, 0, 0),
 datetime.datetime(2016, 1, 5, 0, 0),
 datetime.datetime(2016, 1, 6, 0, 0),
 datetime.datetime(2016, 1, 7, 0, 0),
 datetime.datetime(2016, 1, 8, 0, 0)]

答案 3 :(得分:0)

只需使用月份差异作为计数:

start = datetime(2015, 12, 31)
end = datetime(2016,01,01)
diff_month = lambda e, s: (e.year - s.year)*12 + e.month - s.month
list(rrule(MONTHLY, count=diff_month(end,start)+1, dtstart=start))