2016-01-22 51 views
3

我想要獲得給定範圍內的月份列表。具體來說,給定的範圍2015-12-31 - 2016-01-01,我想獲得列表2015-122016-01如何創建日期範圍,直到包含python dateutils的日期?

我使用的是dateutil的rrule,但until參數並沒有真正的幫助,因爲它似乎在尋找完整的月份。

例如爲:

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月相同的輸出,以及任何一天結束一月。也就是說,我只關心月份爲2015-122016-01的事實。這一天對我來說並不重要,但我只希望每個月只有一個datetime(這些輸入的最大值爲2,對於day組件的值爲最大值)。

是否有一個簡單的解決方案,或者我將不得不增加每日和建立自己的一套月?

回答

3

list(rrule(MONTHLY, dtstart=datetime(2015, 12, 31), until=datetime(2016,01,01)))沒有返回一月的原因是因爲沒有一個月(以MONTHLY參數)在012月31日到1月1日之間。

由於您不需要日間組件,因此我將執行一個小日期操作:

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)] 
+0

很好的回答。雖然,不是'[dt for rrule(...)]'有點冗長'list(rrule(...))'就足夠了。 – AChampion

1

我已經使用幾組做到了:

months = set() 

for dt in rrule(DAILY, dtstart=start_date, until=end_date): 
    months.add(dt.strftime('%Y-%m-.*')) 
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)] 
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)) 
+0

OP想要一個月份列表 – PaulMcG

+0

OP只關心年月,但不要求他們(儘管這將很容易提取)。這將返回DateTime對象中的正確年份 - 月份列表。接受的答案也是一樣的。 – AChampion

+0

對不起,我誤解了您的解決方案,我認爲這只是給予月數而不是月份列表。 – PaulMcG