Chgad
Chgad

Reputation: 882

Python: Iterate over all days in a month

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

Answers (2)

Mad Physicist
Mad Physicist

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

chepner
chepner

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

Related Questions