I want to get all months between now and August 2010, as a list formatted like this:
['2010-08-01', '2010-09-01', .... , '2016-02-01'] Right now this is what I have:
months = [] for y in range(2010, 2016): for m in range(1, 13): if (y == 2010) and m < 8: continue if (y == 2016) and m > 2: continue month = '%s-%s-01' % (y, ('0%s' % (m)) if m < 10 else m) months.append(month) What would be a better way to do this?
Use datetime. timedelta() to iterate through a range of dates date(year, month, day) to return a datetime of representing the time indicated by year , month , and day . Call datetime. timedelta(days=number) to return a timedelta object representing a change in time of the specified number of days.
dateutil.relativedelta is handy here.
I've left the formatting out as an exercise.
from dateutil.relativedelta import relativedelta import datetime result = [] today = datetime.date.today() current = datetime.date(2010, 8, 1) while current <= today: result.append(current) current += relativedelta(months=1)
I had a look at the dateutil documentation. Turns out it provides an even more convenient way than using dateutil.relativedelta: recurrence rules (examples)
For the task at hand, it's as easy as
from dateutil.rrule import * from datetime import date months = map( date.isoformat, rrule(MONTHLY, dtstart=date(2010, 8, 1), until=date.today()) ) Note that we're cheating a little bit, here. The elements dateutil.rrule.rrule produces are of type datetime.datetime, even if we pass dtstart and until of type datetime.date, as we do above. I let map feed them to date's isoformat function, which just turns out to convert them to strings as if it were just dates without any time-of-day information.
Therefore, the seemingly equivalent list comprehension
[day.isoformat() for day in rrule(MONTHLY, dtstart=date(2010, 8, 1), until=date.today())] would return a list like
['2010-08-01T00:00:00', '2010-09-01T00:00:00', '2010-10-01T00:00:00', '2010-11-01T00:00:00', ⋮ '2015-12-01T00:00:00', '2016-01-01T00:00:00', '2016-02-01T00:00:00'] Thus, if we want to use a list comprehension instead of map, we have to do something like
[dt.date().isoformat() for dt in rrule(MONTHLY, dtstart=date(2010, 8, 1), until=date.today())]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With