Python calendar.itermonthdates(): All Dates in Complete Weeks

calendar.Calendar.itermonthdates(year, month) yields datetime.date objects for every day of a month, plus dates from the previous and following months needed to complete each calendar week. The default week starts on Monday.

This example prints every date in the calendar grid for July 2020:

import calendar
my_cal = calendar.Calendar()
for x in my_cal.itermonthdates(2020, 7):
    print(x)

Output (first and last dates):

2020-06-29
2020-06-30
2020-07-01
2020-07-02
2020-07-03
2020-07-04
... (middle dates omitted) ...
2020-07-28
2020-07-29
2020-07-30
2020-07-31
2020-08-01
2020-08-02
Show all 35 output lines
2020-06-29
2020-06-30
2020-07-01
2020-07-02
2020-07-03
2020-07-04
2020-07-05
2020-07-06
2020-07-07
2020-07-08
2020-07-09
2020-07-10
2020-07-11
2020-07-12
2020-07-13
2020-07-14
2020-07-15
2020-07-16
2020-07-17
2020-07-18
2020-07-19
2020-07-20
2020-07-21
2020-07-22
2020-07-23
2020-07-24
2020-07-25
2020-07-26
2020-07-27
2020-07-28
2020-07-29
2020-07-30
2020-07-31
2020-08-01
2020-08-02

The first date is 2020-06-29 and the last is 2020-08-02. Those four adjacent-month dates complete the Monday–Sunday week rows. The iterator contains 35 dates, not just July’s 31 days.

Practice calendar dates in Python

Run the July example, change the starting weekday, filter dates and complete short exercises with self-checking assertions.

Open Python itermonthdates practice in Google Colab View notebook on GitHub

Uses only the Python standard library. Upload the companion notebook to your Python-basics GitHub repository before publishing these links.

itermonthdates() syntax and parameters

Use calendar.Calendar(firstweekday=0).itermonthdates(year, month). The Calendar instance determines the first weekday; the method accepts a year and month.

ArgumentPurposeExample
yearCalendar year to inspect; for this method, returned dates must fit in datetime.date2020
monthMonth number from 1 (January) through 12 (December)7
firstweekdayOptional Calendar constructor setting: Monday 0 to Sunday 65 for Saturday

The result is a Python iterator containing datetime.date objects rather than strings or integer day numbers. Each completed week always contains seven dates. See the first weekday setting for more options.

What type of values does itermonthdates() return?

The method yields real datetime.date objects, allowing date comparisons and formatting without parsing printed strings.

import calendar
from datetime import date
first_date = next(calendar.Calendar().itermonthdates(2020, 7))
print(first_date)
print(type(first_date).__name__)
print(isinstance(first_date, date))

Output:

2020-06-29
date
True

Printing a date displays its ISO-formatted representation. The object itself has date methods and attributes.

Set Saturday as the first weekday

The original Saturday-first example uses firstweekday=5. The month is unchanged, but the first and last dates in its complete-week grid change.

import calendar
my_cal = calendar.Calendar(firstweekday=5)
for x in my_cal.itermonthdates(2020, 7):
    print(x)

Output (first and last dates):

2020-06-27
2020-06-28
2020-06-29
2020-06-30
2020-07-01
2020-07-02
... (middle dates omitted) ...
2020-07-26
2020-07-27
2020-07-28
2020-07-29
2020-07-30
2020-07-31
Show all 35 output lines
2020-06-27
2020-06-28
2020-06-29
2020-06-30
2020-07-01
2020-07-02
2020-07-03
2020-07-04
2020-07-05
2020-07-06
2020-07-07
2020-07-08
2020-07-09
2020-07-10
2020-07-11
2020-07-12
2020-07-13
2020-07-14
2020-07-15
2020-07-16
2020-07-17
2020-07-18
2020-07-19
2020-07-20
2020-07-21
2020-07-22
2020-07-23
2020-07-24
2020-07-25
2020-07-26
2020-07-27
2020-07-28
2020-07-29
2020-07-30
2020-07-31

For this Saturday–Friday calendar, the iterator begins on 2020-06-27 and ends on 2020-07-31. Monday remains weekday 0 and Saturday remains 5; only the displayed week ordering changes.

Display year, month and day separately

Each result has .year, .month and .day attributes. This keeps the original example for extracting these values.

import calendar
my_cal = calendar.Calendar()
for x in my_cal.itermonthdates(2020, 7):
    print("Year:", x.year, ", Month:", x.month, ", Day :", x.day)

Output (selected lines):

Year: 2020 , Month: 6 , Day : 29
Year: 2020 , Month: 6 , Day : 30
Year: 2020 , Month: 7 , Day : 1
Year: 2020 , Month: 7 , Day : 2
... (middle dates omitted) ...
Year: 2020 , Month: 7 , Day : 30
Year: 2020 , Month: 7 , Day : 31
Year: 2020 , Month: 8 , Day : 1
Year: 2020 , Month: 8 , Day : 2
Show all 35 output lines
Year: 2020 , Month: 6 , Day : 29
Year: 2020 , Month: 6 , Day : 30
Year: 2020 , Month: 7 , Day : 1
Year: 2020 , Month: 7 , Day : 2
Year: 2020 , Month: 7 , Day : 3
Year: 2020 , Month: 7 , Day : 4
Year: 2020 , Month: 7 , Day : 5
Year: 2020 , Month: 7 , Day : 6
Year: 2020 , Month: 7 , Day : 7
Year: 2020 , Month: 7 , Day : 8
Year: 2020 , Month: 7 , Day : 9
Year: 2020 , Month: 7 , Day : 10
Year: 2020 , Month: 7 , Day : 11
Year: 2020 , Month: 7 , Day : 12
Year: 2020 , Month: 7 , Day : 13
Year: 2020 , Month: 7 , Day : 14
Year: 2020 , Month: 7 , Day : 15
Year: 2020 , Month: 7 , Day : 16
Year: 2020 , Month: 7 , Day : 17
Year: 2020 , Month: 7 , Day : 18
Year: 2020 , Month: 7 , Day : 19
Year: 2020 , Month: 7 , Day : 20
Year: 2020 , Month: 7 , Day : 21
Year: 2020 , Month: 7 , Day : 22
Year: 2020 , Month: 7 , Day : 23
Year: 2020 , Month: 7 , Day : 24
Year: 2020 , Month: 7 , Day : 25
Year: 2020 , Month: 7 , Day : 26
Year: 2020 , Month: 7 , Day : 27
Year: 2020 , Month: 7 , Day : 28
Year: 2020 , Month: 7 , Day : 29
Year: 2020 , Month: 7 , Day : 30
Year: 2020 , Month: 7 , Day : 31
Year: 2020 , Month: 8 , Day : 1
Year: 2020 , Month: 8 , Day : 2

Use date.year, date.month and date.day to build a custom label. You do not need to split the date string manually.

Count the dates and inspect the boundaries

Convert the iterator to a list when you need its length or want to access individual dates by index.

import calendar
all_dates = list(calendar.Calendar().itermonthdates(2020, 7))
print("Total dates:", len(all_dates))
print("First:", all_dates[0])
print("Last:", all_dates[-1])
print("Whole weeks:", len(all_dates) // 7)

Output:

Total dates: 35
First: 2020-06-29
Last: 2020-08-02
Whole weeks: 5

Depending on the month and firstweekday, the complete calendar grid can span four, five, or six weeks. That gives 28, 35, or 42 dates.

Filter out previous- and next-month dates

A frequent requirement is to keep only the dates belonging to the selected month. Check both year and month, particularly around December and January.

import calendar
selected_year, selected_month = 2020, 7
all_dates = calendar.Calendar().itermonthdates(selected_year, selected_month)
month_dates = [d for d in all_dates
               if d.year == selected_year and d.month == selected_month]
print("Dates in month:", len(month_dates))
print("First:", month_dates[0])
print("Last:", month_dates[-1])

Output:

Dates in month: 31
First: 2020-07-01
Last: 2020-07-31

July has 31 dates; the four extra values from June and August are excluded. For examples using simple day numbers and 0 outside the month, see itermonthdays().

Identify the dates outside the chosen month

Those extra dates are useful when displaying a full monthly calendar grid. You can style them differently in a calendar application.

import calendar
all_dates = calendar.Calendar().itermonthdates(2020, 7)
adjacent = [d for d in all_dates if (d.year, d.month) != (2020, 7)]
print("Adjacent-month dates:", len(adjacent))
for day in adjacent:
    print(day)

Output:

Adjacent-month dates: 4
2020-06-29
2020-06-30
2020-08-01
2020-08-02

For July 2020, two padding dates come from June and two from August. These values are real dates, not placeholders.

Begin the week on Sunday

Pass the readable constant calendar.SUNDAY rather than remembering the number 6.

import calendar
cal = calendar.Calendar(firstweekday=calendar.SUNDAY)
dates = list(cal.itermonthdates(2020, 7))
print("First weekday number:", cal.getfirstweekday())
print("First date:", dates[0])
print("Last date:", dates[-1])
print("Number of dates:", len(dates))

Output:

First weekday number: 6
First date: 2020-06-28
Last date: 2020-08-01
Number of dates: 35

The year and month stay the same; only the boundaries of the complete Sunday–Saturday weeks change.

Update firstweekday after creating Calendar

You can change an existing Calendar instance using setfirstweekday(). The change affects future iterations, not an already-created list of dates.

import calendar
cal = calendar.Calendar()
before = list(cal.itermonthdates(2020, 7))
cal.setfirstweekday(calendar.FRIDAY)
after = list(cal.itermonthdates(2020, 7))
print("Before:", before[0], "to", before[-1])
print("After:", after[0], "to", after[-1])

Output:

Before: 2020-06-29 to 2020-08-02
After: 2020-06-26 to 2020-08-06

For related methods that yield weekday numbers, read iterweekdays().

Group consecutive dates into seven-day weeks

Because itermonthdates() always yields complete weeks for ordinary supported dates, split the list into groups of seven to build calendar rows.

import calendar
dates = list(calendar.Calendar().itermonthdates(2020, 7))
for start in range(0, len(dates), 7):
    week = dates[start:start + 7]
    print(" ".join(f"{d.day:02d}" for d in week))

Output:

29 30 01 02 03 04 05
06 07 08 09 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 01 02

This prints five Monday–Sunday rows. The first row includes June 29 and 30; the last includes August 1 and 2, even though the output shows only day numbers.

itermonthdates() vs monthdatescalendar()

If you prefer a ready-made list of weeks, use Calendar.monthdatescalendar(). It produces a list of week lists, whereas itermonthdates() yields dates one at a time.

import calendar
cal = calendar.Calendar()
weeks = cal.monthdatescalendar(2020, 7)
print("Number of weeks:", len(weeks))
print("Dates in first week:", len(weeks[0]))
print("First week:", weeks[0])
print("Same flat dates:", [d for week in weeks for d in week]
      == list(cal.itermonthdates(2020, 7)))

Output:

Number of weeks: 5
Dates in first week: 7
First week: [datetime.date(2020, 6, 29), datetime.date(2020, 6, 30), datetime.date(2020, 7, 1), datetime.date(2020, 7, 2), datetime.date(2020, 7, 3), datetime.date(2020, 7, 4), datetime.date(2020, 7, 5)]
Same flat dates: True

This is a convenient starting point for building one HTML table row per week. If you want a printable text calendar instead, see prmonth().

Display weekday names alongside each date

The .weekday() method uses Monday = 0 through Sunday = 6. Use strftime() for readable weekday names.

import calendar
days = list(calendar.Calendar().itermonthdates(2020, 7))[:7]
for d in days:
    print(d.isoformat(), d.weekday(), d.strftime("%A"))

Output:

2020-06-29 0 Monday
2020-06-30 1 Tuesday
2020-07-01 2 Wednesday
2020-07-02 3 Thursday
2020-07-03 4 Friday
2020-07-04 5 Saturday
2020-07-05 6 Sunday

This can help with booking interfaces or calendars that show dates with weekday labels. The weekday number does not change when you set a different calendar first weekday.

Create a list of working days

To obtain only Monday-to-Friday dates in July, combine the month filter with d.weekday() < 5. This example does not account for public holidays.

import calendar
cal = calendar.Calendar()
workdays = [d for d in cal.itermonthdates(2020, 7)
            if (d.year, d.month) == (2020, 7) and d.weekday() < 5]
print("Weekdays in July 2020:", len(workdays))
print("First workday:", workdays[0])
print("Last workday:", workdays[-1])

Output:

Weekdays in July 2020: 23
First workday: 2020-07-01
Last workday: 2020-07-31

The condition filters to the requested month and excludes Saturdays and Sundays. Business-specific holidays require an additional holiday calendar.

Try a leap-year month

The method automatically includes February 29 in a leap year. You do not need separate date-generation logic for that month.

import calendar
cal = calendar.Calendar()
all_dates = list(cal.itermonthdates(2024, 2))
february = [d for d in all_dates if d.month == 2 and d.year == 2024]
print("February dates:", len(february))
print("Contains Feb 29:", any(d.day == 29 for d in february))
print("Calendar begins:", all_dates[0])
print("Calendar ends:", all_dates[-1])

Output:

February dates: 29
Contains Feb 29: True
Calendar begins: 2024-01-29
Calendar ends: 2024-03-03

See the Python calendar module tutorial for related leap-year utilities and calendar formatting methods.

Use dates in calculations and formatting

Because values are real datetime.date objects, they support adding timedelta and formatting with strftime().

import calendar
from datetime import timedelta
dates = calendar.Calendar().itermonthdates(2020, 7)
first_day = next(d for d in dates if (d.year, d.month, d.day) == (2020, 7, 1))
print("Original:", first_day)
print("One week later:", first_day + timedelta(days=7))
print("Formatted:", first_day.strftime("%d %B %Y"))

Output:

Original: 2020-07-01
One week later: 2020-07-08
Formatted: 01 July 2020

Use the resulting date objects directly for scheduling; do not perform arithmetic on formatted date strings.

Remember that an iterator is consumed once

An iterator advances as you read it. After you exhaust it, a second loop over the same iterator has nothing left to yield. Create a new iterator or convert it to a list if you need to reuse the dates.

import calendar
cal = calendar.Calendar()
dates = cal.itermonthdates(2020, 7)
print("First item:", next(dates))
print("Remaining:", len(list(dates)))
print("After exhaustion:", len(list(dates)))
print("New iterator:", len(list(cal.itermonthdates(2020, 7))))

Output:

First item: 2020-06-29
Remaining: 34
After exhaustion: 0
New iterator: 35

The same one-time-consumption rule applies to many other Python iterators; see Python iterators.

Compare itermonthdates() with other month iterators

Related calendar methods return different kinds of values. Choose the one that matches the information you need.

import calendar
cal = calendar.Calendar()
print("dates:", list(cal.itermonthdates(2020, 7))[:3])
print("days:", list(cal.itermonthdays(2020, 7))[:3])
print("days2:", list(cal.itermonthdays2(2020, 7))[:3])
print("days3:", list(cal.itermonthdays3(2020, 7))[:3])

Output:

dates: [datetime.date(2020, 6, 29), datetime.date(2020, 6, 30), datetime.date(2020, 7, 1)]
days: [0, 0, 1]
days2: [(0, 0), (0, 1), (1, 2)]
days3: [(2020, 6, 29), (2020, 6, 30), (2020, 7, 1)]
MethodReturned dataIdeal use
itermonthdates()datetime.dateDate arithmetic, formatting, scheduling
itermonthdays()Day numbers, 0 outside monthSimple month grids
itermonthdays2()(day, weekday) tuplesWeekday-aware numbered grids
itermonthdays3()(year, month, day) tuplesDate parts, including out-of-range years

Also see iterweekdays(), which returns one week of weekday numbers and does not generate month dates.

Date-range limitations at the earliest and latest years

itermonthdates() uses datetime.date, which supports years 1 through 9999. At the boundaries, full weeks might need dates outside that range, which cannot be represented as date objects. Use itermonthdays3() for year/month/day integer tuples when exploring those extreme ranges.

import calendar
cal = calendar.Calendar()
values = list(cal.itermonthdays3(9999, 12))
print("First tuple:", values[0])
print("Last tuple:", values[-1])
print("Number of cells:", len(values))

Output:

First tuple: (9999, 11, 29)
Last tuple: (10000, 1, 2)
Number of cells: 35

The integer tuples can represent a year beyond 9999 when padding a calendar; converting them to datetime.date would not be valid. Normal modern-year calendars do not have this boundary problem.

Handle invalid month numbers

month must be between 1 and 12. When the iterator is evaluated, an invalid month raises calendar.IllegalMonthError (a subclass of ValueError).

import calendar
try:
    dates = list(calendar.Calendar().itermonthdates(2020, 13))
except calendar.IllegalMonthError:
    print("Please enter a month from 1 to 12")

Output:

Please enter a month from 1 to 12

Validate data from forms or external inputs before using it in a calendar application. Avoid silently converting an invalid month to another month.

Practical example: assign tasks to weekdays

This small scheduling example creates a task only for weekdays within July 2020, not the extra padding dates or weekends.

import calendar
cal = calendar.Calendar()
assigned = 0
for d in cal.itermonthdates(2020, 7):
    if (d.year, d.month) == (2020, 7) and d.weekday() < 5:
        assigned += 1
        if assigned <= 3:
            print(d.isoformat(), "Review project tasks")
print("Total assigned days:", assigned)

Output:

2020-07-01 Review project tasks
2020-07-02 Review project tasks
2020-07-03 Review project tasks
Total assigned days: 23

For a real scheduling system, add a holiday list and store task assignments using your application’s data layer.

Which Python calendar method should you use?

Use itermonthdates() when you want to iterate complete weeks and need fully functional date objects. Use monthdatescalendar() when you specifically need pre-grouped weeks, itermonthdays() when day numbers are enough, or prmonth() when you just want to print a calendar. These tools solve related but different problems.

Common errors and troubleshooting

ProblemWhy it happensSolution
Extra dates appear before or after the monthThe method completes seven-day weeks by designFilter by both year and month if you only need target-month dates
Week starts on the wrong dayThe default is MondayPass firstweekday=calendar.SUNDAY or another weekday when creating Calendar
len() does not work on the iteratorThe result is an iterator rather than a listUse list(cal.itermonthdates(...)) before calling len()
Second iteration yields no datesThe same iterator was exhaustedCreate a fresh iterator or keep a list of results
Invalid month raises an exceptionMonth number is not in 1–12Validate input and handle calendar.IllegalMonthError
Out-of-range year errorsdatetime.date has a limited year rangeUse itermonthdays3() when numeric tuples are sufficient

Practice exercises

  1. Change the first weekday from Monday to Sunday and note the first and last dates of July 2020.
  2. Get only the dates in February 2024 and verify that the result contains 29 days.
  3. Count the weekdays in a month, excluding Saturdays and Sundays.
  4. Split July 2020 into lists of seven dates and print each week on a separate line.
  5. Compare the types returned by itermonthdates() and itermonthdays3().

Start the interactive Colab practice notebook to run the examples and check your answers. If you are new to Colab, read the Google Colab tutorial.

Frequently asked questions

What does calendar.itermonthdates() return?

An iterator of datetime.date objects covering the requested month and the preceding/following dates needed to complete weeks.

Why does it include dates from other months?

Complete weekly rows let you build a monthly calendar grid without gaps. Filter by year and month if you only need dates inside the month.

What is the default first weekday?

Monday (0), unless you configure a different firstweekday on the Calendar object.

How many dates does the iterator yield?

Normally 28, 35 or 42 dates: four, five or six complete seven-day weeks, depending on month and starting weekday.

Does it return strings or actual date objects?

Actual datetime.date objects. They print in ISO-like format but can be compared, formatted and used for date arithmetic.

How do I generate only the selected month?

Use a comprehension keeping values whose (date.year, date.month) matches the requested year and month.

Can I use it directly in Google Colab?

Yes. calendar and datetime belong to the standard library; no extra installation is needed.

What happens for January in year 1 or December in year 9999?

Padding may fall outside the datetime.date range. Use itermonthdays3() for numeric tuples at those boundaries.

What is the difference between itermonthdates() and monthdatescalendar()?

Both provide date objects for complete weeks. itermonthdates() is a flat iterator; monthdatescalendar() returns a list of week lists.

Ready to experiment? Return to the Colab and GitHub practice notebook.

Back to top ↑




Subscribe to our YouTube Channel here



plus2net.com







Python Video Tutorials
Python SQLite Video Tutorials
Python MySQL Video Tutorials
Python Tkinter Video Tutorials
✖
We use cookies to improve your browsing experience. . Learn more
HTML MySQL PHP JavaScript ASP Photoshop Articles Contact us
© 2000-2026 plus2net.com All rights reserved worldwide Privacy Policy Disclaimer