To work with convenient date objects, always use the standard module datetime
. This wraps your string formatted dates, and allows easier calculations as well as tailored output formatting.
Unfortunately, it seems to miss one important piece of information: the last day of each month, given a year (which is necessary for Februari). There is an additional module calendar
which returns the last day for a month, but since this is all you need of it and there is a simple datetime
based function that does the same thing, I chose the latter.
With that, you can set any begin
date and append it to your list, together with its last day of that month, then set begin
to the next month's 1st and continue until you pass end
.
A caveat/finetuning: I realized it would not work if both begin
and end
fall inside the same month. That needs an interim check, so I changed my initial while begin < end
to while True
and moved the check for crossing the end date into a separate line.
Also, to cross a year needs a separate test again, because else the statement month+1
will fail on December.
import datetime
# borrowed from https://stackoverflow.com/a/13565185
# as noted there, the calendar module has a function of its own
def last_day_of_month(any_day):
next_month = any_day.replace(day=28) + datetime.timedelta(days=4) # this will never fail
return next_month - datetime.timedelta(days=next_month.day)
begin = "2018-02-15"
end = "2018-04-23"
def monthlist(begin,end):
begin = datetime.datetime.strptime(begin, "%Y-%m-%d")
end = datetime.datetime.strptime(end, "%Y-%m-%d")
result = []
while True:
if begin.month == 12:
next_month = begin.replace(year=begin.year+1,month=1, day=1)
else:
next_month = begin.replace(month=begin.month+1, day=1)
if next_month > end:
break
result.append ([begin.strftime("%Y-%m-%d"),last_day_of_month(begin).strftime("%Y-%m-%d")])
begin = next_month
result.append ([begin.strftime("%Y-%m-%d"),end.strftime("%Y-%m-%d")])
return result
date_list = monthlist(begin,end)
print (date_list)
results in
[ ['2018-02-15', '2018-02-28'],
['2018-03-01', '2018-03-31'],
['2018-04-01', '2018-04-23'] ]
(slightly formatted for readability only)