生成给定期间按月细分的日期范围 [英] Generate date ranges broken by month for a given period
本文介绍了生成给定期间按月细分的日期范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我在努力写一个pythonic,清洁的生成器方法,给定一个日期期间,如 ['2014-01-15','2015-02-03]
,会给我这个:
I'm struggling with writing a pythonic, clean generator method that, given a date period, like ['2014-01-15', '2015-02-03]
, will give me this:
['2014-01-15', '2014-01-31']
['2014-02-01', '2014-02-28']
...
['2015-02-01', '2015-02-03']
这是我想出来的:
from datetime import datetime
import calendar
def genDatePeriods(startDate, endDate, format='%Y-%m-%d'):
dt1 = datetime.strptime(startDate, format)
dt2 = datetime.strptime(endDate, format)
for year in range(dt1.year, dt2.year + 1):
for month in range(1, 13):
day0 = dt1.day if month == dt1.month and year == dt1.year else 1
day1 = dt2.day if month == dt2.month and year == dt2.year else calendar.monthrange(year, month)[1]
if (year == dt1.year and month < dt1.month) or (year == dt2.year and month > dt2.month):
continue
else:
d0 = (year, month, day0)
d1 = (year, month, day1)
yield [datetime(*d).strftime(format) for d in [d0, d1]]
我觉得有更多的pythonic /整洁/高效的方式来做到这一点。任何想法?
It works, however I feel like there is a more pythonic/tidy/efficient way to do this. Any ideas?
推荐答案
以下是更简洁,使用 datetime.date c $ c>对象,每次查找下一个月的第一天,直到到达结束日期:
The following is much more concise, using datetime.date()
objects to find the first day of the next month each time, until you reach the end date:
from datetime import datetime, timedelta
def genDatePeriods(startDate, endDate, format='%Y-%m-%d'):
curr = datetime.strptime(startDate, format).date()
end = datetime.strptime(endDate, format).date()
while curr <= end:
# first day of the next month, using modular arithmetic
next_month = curr.replace(
month=curr.month % 12 + 1, year=curr.year + curr.month // 12,
day=1)
curr_formatted = curr.strftime(format)
# end date is next month's first day, minus one day,
# or the given endDate, whichever comes first
end_formatted = min(next_month - timedelta(days=1), end).strftime(format)
yield [curr_formatted, end_formatted]
curr = next_month
b $ b
演示:
Demo:
>>> for res in genDatePeriods('2014-01-15', '2015-02-03'):
... print res
...
['2014-01-15', '2014-01-31']
['2014-02-01', '2014-02-28']
['2014-03-01', '2014-03-31']
['2014-04-01', '2014-04-30']
['2014-05-01', '2014-05-31']
['2014-06-01', '2014-06-30']
['2014-07-01', '2014-07-31']
['2014-08-01', '2014-08-31']
['2014-09-01', '2014-09-30']
['2014-10-01', '2014-10-31']
['2014-11-01', '2014-11-30']
['2014-12-01', '2014-12-31']
['2015-01-01', '2015-01-31']
['2015-02-01', '2015-02-03']
这篇关于生成给定期间按月细分的日期范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文