Python calendar.prmonth(): Print a Monthly Text Calendar

calendar.TextCalendar.prmonth() prints a month as an aligned, plain-text calendar. Pass a year and month, and optionally adjust the date-column width (w) and lines per week (l).

Here is a complete example printing July 2020 with wider date columns:

import calendar
x = calendar.TextCalendar()
x.prmonth(2020, 7, w=5, l=1)

Output:

                July 2020
 Mon   Tue   Wed   Thu   Fri   Sat   Sun
               1     2     3     4     5
   6     7     8     9    10    11    12
  13    14    15    16    17    18    19
  20    21    22    23    24    25    26
  27    28    29    30    31

The output starts on Monday because TextCalendar() defaults to Monday (0). Spaces align the dates into columns, so use a monospaced font to display the result correctly.

Practice this calendar in Python

Run the example, switch the first weekday, change w and l, and complete exercises with automatic checks.

Open prmonth practice notebook in Google Colab View practice notebook on GitHub

The notebook uses only Python's standard library. Publish the companion notebook to your Python-basics repository before using these links.

prmonth() syntax and parameters

The method belongs to calendar.TextCalendar. Its signature is prmonth(theyear, themonth, w=0, l=0).

ParameterMeaningExample
theyearYear to display2020
themonthMonth number from 1 (January) to 12 (December)7
wMinimum width of the date columns in text characters; omitted or 0 uses the effective minimum of 2w=5
lLines allocated to each week; omitted or 0 uses the effective minimum of 1l=2

Note: w is character spacing, not CSS pixels; l adds vertical spacing between calendar weeks. These are formatting settings, not the number of weekdays or weeks printed.

Start the week on Friday

Weekday numbering is fixed: Monday is 0, Tuesday 1, through Sunday 6. A Friday-first calendar begins each row with Friday, but it does not renumber the days. This retains the original example.

import calendar
x = calendar.TextCalendar()
x.setfirstweekday(4)  # Friday
x.prmonth(theyear=2020, themonth=7, w=3, l=0)

Output:

         July 2020
Fri Sat Sun Mon Tue Wed Thu
                      1   2
  3   4   5   6   7   8   9
 10  11  12  13  14  15  16
 17  18  19  20  21  22  23
 24  25  26  27  28  29  30
 31

The same July dates appear under a Friday–Thursday header. To understand the setting, see setting the first weekday in Python and iterating weekday numbers.

Use the module-level calendar.prmonth() shortcut

For a normal Monday-first calendar you can call calendar.prmonth() directly, without creating a TextCalendar object. This uses the calendar module's configured first weekday.

import calendar
calendar.prmonth(2020, 7)

Output:

     July 2020
Mo Tu We Th Fr Sa Su
       1  2  3  4  5
 6  7  8  9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31

For code needing different start days in different places, use separate TextCalendar instances. That avoids changing the module-level first-weekday setting for other code.

Change date-column width (w)

A larger w allocates more characters to each date column. Below, w=2 keeps the calendar compact; compare it with the first example's w=5.

import calendar
x = calendar.TextCalendar()
x.prmonth(2020, 7, w=2, l=1)

Output:

     July 2020
Mo Tu We Th Fr Sa Su
       1  2  3  4  5
 6  7  8  9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31

When w is 0 or 1, Python still needs at least two characters for date values such as 30 and 31.

Add vertical space between weeks (l)

Use l=2 to leave a blank line after each week. This makes a printed schedule easier to annotate, but it doesn't change which dates belong to each week.

import calendar
x = calendar.TextCalendar()
x.prmonth(2020, 7, w=2, l=2)

Output:

     July 2020

Mo Tu We Th Fr Sa Su

       1  2  3  4  5

 6  7  8  9 10 11 12

13 14 15 16 17 18 19

20 21 22 23 24 25 26

27 28 29 30 31

With l=0 or l=1, the calendar uses one line for each week.

Print a Sunday-first calendar

You can pass calendar.SUNDAY rather than remembering that Sunday is 6. The order changes without changing date values.

import calendar
x = calendar.TextCalendar(firstweekday=calendar.SUNDAY)
x.prmonth(2020, 7, w=2, l=1)

Output:

     July 2020
Su Mo Tu We Th Fr Sa
          1  2  3  4
 5  6  7  8  9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Change an existing TextCalendar's starting weekday

Use setfirstweekday() on the object to change its display order. Below, the two headers show the effect without printing the whole month twice.

import calendar
x = calendar.TextCalendar()
print(x.formatmonth(2020, 7).splitlines()[1])
x.setfirstweekday(calendar.FRIDAY)
print(x.formatmonth(2020, 7).splitlines()[1])

Output:

Mo Tu We Th Fr Sa Su
Fr Sa Su Mo Tu We Th

setfirstweekday() changes this TextCalendar instance; it does not change the names or fixed weekday numbers.

prmonth() vs formatmonth(): print or return text?

This distinction is useful when you want to keep the calendar for an email, text file, or log. prmonth() writes to standard output; formatmonth() returns the same layout as a string.

import calendar
x = calendar.TextCalendar()
month_text = x.formatmonth(2020, 7)
print(type(month_text).__name__)
print(month_text.splitlines()[0].strip())
print(month_text.splitlines()[1])

Output:

str
July 2020
Mo Tu We Th Fr Sa Su

formatmonth() does not automatically print anything. The print() calls above display selected lines from the returned string.

Why does prmonth() return None?

prmonth() is designed for direct output, not for creating a reusable string. Assigning its result to a variable still prints the calendar, but the assigned value is None.

import calendar
x = calendar.TextCalendar()
result = x.prmonth(2020, 7)
print("Returned None:", result is None)

Output:

     July 2020
Mo Tu We Th Fr Sa Su
       1  2  3  4  5
 6  7  8  9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Returned None: True

If you need a string, call formatmonth() instead of trying to concatenate or save result.

Capture text printed by prmonth()

If you must capture output from existing code that calls prmonth(), use contextlib.redirect_stdout() with io.StringIO(). For new code, formatmonth() is simpler.

import calendar
from contextlib import redirect_stdout
from io import StringIO

buffer = StringIO()
with redirect_stdout(buffer):
    calendar.prmonth(2020, 7)
text = buffer.getvalue()
print(text.splitlines()[0].strip())
print("Characters captured:", len(text) > 50)

Output:

July 2020
Characters captured: True

The redirected text contains newlines and alignment spaces. This is suitable for capturing plain-text output; it is not HTML markup.

Save a monthly calendar to a text file

Because formatmonth() returns a string, it is the direct option for saving a calendar. This example creates july-2020-calendar.txt in the folder where Python is running.

import calendar
from pathlib import Path

x = calendar.TextCalendar()
path = Path("july-2020-calendar.txt")
path.write_text(x.formatmonth(2020, 7), encoding="utf-8")
print("Saved:", path.name)
print("Month:", path.read_text(encoding="utf-8").splitlines()[0].strip())

Output:

Saved: july-2020-calendar.txt
Month: July 2020

On Colab the file is created in the runtime's working directory. It is not automatically uploaded to GitHub or saved permanently to your Google Drive.

Display several months with a loop

A loop can print a consecutive set of calendars. This compact example prints the title lines for June through August 2020; remove .splitlines()[0].strip() to display each full calendar using formatmonth().

import calendar
x = calendar.TextCalendar()
for month in (6, 7, 8):
    title = x.formatmonth(2020, month).splitlines()[0].strip()
    print(title)

Output:

June 2020
July 2020
August 2020

You can also replace the loop body with x.prmonth(2020, month) to print three complete month grids.

Validate a month before printing

Month values must be integers from 1 to 12. The example checks user-supplied values before calling prmonth(); web applications should also validate the year and handle malformed input.

import calendar

year = 2024
month = 13
if isinstance(month, int) and 1 <= month <= 12:
    calendar.prmonth(year, month)
else:
    print("Please enter a month from 1 to 12.")

Output:

Please enter a month from 1 to 12.

Calling calendar.prmonth(2024, 13) directly raises an exception for the invalid month. Validate external input and avoid passing arbitrary strings directly to calendar functions.

Check weekdays and leap-year dates

The calendar module handles leap years automatically. monthrange() is useful when you need a month's starting weekday and number of days, rather than a printed grid.

import calendar
print("February 2024:", calendar.monthrange(2024, 2))
print("February 2023:", calendar.monthrange(2023, 2))
print("July 1, 2020 weekday:", calendar.weekday(2020, 7, 1))

Output:

February 2024: (calendar.THURSDAY, 29)
February 2023: (calendar.WEDNESDAY, 28)
July 1, 2020 weekday: 2

The weekday returned for July 1, 2020 is 2 (Wednesday). This numerical convention stays the same even if your printed calendar begins on Friday or Sunday.

Which calendar function should I use?

FunctionResultGood for
calendar.prmonth(year, month)Prints a text calendarSimple scripts and console output
calendar.TextCalendar().prmonth(...)Prints a text calendar with object-specific week settingsCustom week starts
calendar.TextCalendar().formatmonth(...)Returns a multiline stringSaving and reusing text
calendar.month(year, month)Returns a multiline string using module settingsQuick string formatting
calendar.HTMLCalendar().formatmonth(...)Returns HTML table markupHTML calendar pages
calendar.monthrange(year, month)Returns starting weekday and day countDate calculations

For details of raw date iteration, explore itermonthdays(), itermonthdays2(), and itermonthdays3().

Common errors and troubleshooting

The calendar looks misaligned in a webpage

Text calendars rely on spaces. Display output in a <pre> element or another element styled with a monospaced font and white-space: pre. Plain HTML collapses repeated spaces and newlines.

I get None instead of a calendar string

prmonth() prints its output and returns None. Use formatmonth() for text you want to store or manipulate.

The month begins on the wrong weekday

Pass firstweekday=calendar.SUNDAY or call setfirstweekday() on your TextCalendar object. See firstweekday options.

Invalid month number or a TypeError

Use an integer month between 1 and 12. A form value such as "7" is a string and should be validated and converted before calling the calendar method.

Changing w or l has no effect

Values below the effective minimum are treated as the minimum: two characters per date column and one line per week. Try w=5 or l=2 to see the difference.

Practice exercises

Try these challenges using the Colab notebook above. Its cells include solutions and self-checking assertions.

  1. Print your birth month with Monday as the first weekday.
  2. Reprint the same month with Sunday as the first weekday.
  3. Compare how w=2 and w=5 change the output.
  4. Print a month with l=2; count the blank lines added between weeks.
  5. Use formatmonth() to save a month calendar as a text file.
  6. Write an input check rejecting month 13 before rendering a calendar.

Small challenge: Can you display the month name using calendar.month_name[month] without printing the full grid?

Frequently asked questions

What does prmonth() do in Python?

It prints a formatted, plain-text calendar for a given year and month.

Is prmonth() a function or a class method?

Both calendar.prmonth() and calendar.TextCalendar().prmonth() are available. The latter is an instance method you can configure independently.

Does prmonth() return a string?

No. Its return value is None. Use formatmonth() or calendar.month() for a string.

How do I start the calendar on Sunday?

Use calendar.TextCalendar(firstweekday=calendar.SUNDAY) or set the weekday to 6 on the object.

Do I need to install calendar for Google Colab?

No. calendar is part of the Python standard library.

Can I make an HTML calendar with prmonth()?

Not directly: prmonth() produces plain text. For an HTML table, use calendar.HTMLCalendar().formatmonth() and handle any custom content with appropriate HTML escaping.

Does prmonth() handle leap years?

Yes. The printed February calendar uses the actual number of days for the selected year.

Want to work through the examples? Open the Colab or 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