从日期列表中生成元组列表(年,月,日_in_month,full_month)

时间:2015-11-16 15:36:58

标签: python list date datetime

我有一个由以下日期生成的日期列表:

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

3 个答案:

答案 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)

所以:

  1. 我在这里了解了月份范围:How do we determine the number of days for a given month in python
  2. 我的解决方案很糟糕,因为它总共会执行3个循环:列表推导的初始循环,以及我添加的两个循环。由于您正在为了列表理解而走过这些日子,因此可以对此进行优化,以便在单个循环中运行。
  3. 我没有测试它:)

答案 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个给定日期具有相同月份的情况。