我有一个由以下日期生成的日期列表:
from dateutil import parser
from datetime import date, timedelta
d1 = parser.parse("2015-11-25")
d2 = parser.parse("2016-02-06")
delta = (d2-d1).days
date_list = [d1 + timedelta(days=x) for x in range(0, delta+1)]
在此列表中,2015年11月有6天,2015年12月为31天,2016年1月为31天,2016年2月为6天。2015年12月和2016年1月是“完整”月份,即日期列表已包含那几个月的所有日子。
如何在python中以编程方式获取此信息,以便生成如下列表:
[(2015,11,6,False),(2015,12,31,True),(2016,1,31,True),(2016,2,6,False)]
答案 0 :(得分:1)
找到了一个简洁的解决方案:
from dateutil import parser
from datetime import date, timedelta
from collections import Counter
from calendar import monthrange
d1 = parser.parse("2015-11-25")
d2 = parser.parse("2016-02-06")
delta = (d2-d1).days
date_list = [d1 + timedelta(days=x) for x in range(0, delta+1)]
month_year_list = [(d.year, d.month) for d in date_list]
result = [(k[0],k[1],v , True if monthrange(k[0], k[1])[1] == v else
False) for k,v in Counter(month_year_list).iteritems()]
print result
答案 1 :(得分:0)
走完列表并累计每年/每月组合的天数:
import collections
days_in_year_month = defaultdict(int)
for each_date in date_list:
days_in_year_month[(each_date.year, each_date.month)] += 1
接下来输出每年,每月,每个计数和T / F的元组:
import calendar
result = []
for year_month in date_list.keys():
days_in_ym = days_in_year_month([year_month[0], year_month[1])
is_complete = days_in_ym == calendar.monthrange(year_month[0], year_month[1])[1]
result.append(year_month[0], year_month[1], days_in_ym, is_complete)
所以:
答案 2 :(得分:0)
前面提到的解决方案似乎没问题,但是我相信我有一个更优化的解决方案,因为它们需要计算包含所有日期的列表。对于较小的日期差异,这不会有问题。但是,如果差异增加,您的列表将变得更大。
我想提供另一种更直观的方法,因为您基本上知道日期之间的所有月份都已满,并且日期的月份本身并未满。
我尝试利用这些信息,循环只会迭代日期之间的月份。
代码:
from dateutil import parser
from calendar import monthrange
d1 = parser.parse("2015-11-25")
d2 = parser.parse("2016-02-06")
# needed to calculate amount of months between the dates
m1 = d1.year * 12 + (d1.month- 1)
m2 = d2.year * 12 + (d2.month - 1)
result = []
# append first month since this will not be full
result.append((d1.year,d1.month,monthrange(d1.year, d1.month)[1]-d1.day+1,False))
current_month = d1.month
current_year = d1.year
# loop through the months and years that follow d1.
for _ in xrange(0,(m2-m1)-1):
if current_month+1 > 12:
current_month = 1
current_year += 1
else:
current_month += 1
result.append((current_year,current_month,monthrange(current_year, current_month)[1],True))
# append last month since this will not be full either.
result.append((d2.year,d2.month,d2.day,False))
print result
请记住,我给出的代码是一个示例,它不支持例如2个给定日期具有相同月份的情况。