Reputation: 882
Is there a simple way to iterate over all days in a given month?
I would like to have a method where the object I'm iterating over has the days as datetime.date
objects. I have already found the calendar
module with its Calendar
class and respective method itermonthdates(year, month)
.
My problem with this is that the resulting iterator contains "filler" days to represent complete weeks. For example July 2019 Ends on a Wednesday (31). so the week is incomplete and itermonthdates()
adds the dates 1-4 August.
I DO NOT want this behavior.
My first guess is something like:
from calendar import Calendar, monthrange
c = Calendar()
for date in list(c.itermonthdates(2019, 7))[:monthrange(2019, 7)[1]]:
print(date)
which behaves as expected, but I'm not sure if there is a nicer, more elegant way of doing this.
Upvotes: 4
Views: 13276
Reputation: 114420
The calendar
module is designed to display calendars. You are better off using calendar.monthlen
in combination with datetime.date
itself to get your iterator, if you are looking for something straightforward:
def date_iter(year, month):
for i in range(1, calendar.monthlen(year, month) + 1):
yield date(year, month, i)
for d in date_iter(2019, 12):
print(d)
You can of course write the whole thing as a one-liner:
for d in (date(2019, 12, i) for i in range(1, calendar.monthlen(2019, 12) + 1)):
print(d)
The monthlen
attribute appears to be a public, but undocumented attribute of calendar
in Python 3.7. It is analogous to the second element of monthrange
, so you can replace it with monthrange(year, month)[1]
in the code above.
Upvotes: 7
Reputation: 531693
Just filter the date
objects by month.
for d in [x for x in c.itermonthdates(2019, 7) if x.month == 7]:
Upvotes: 13