Printing a Calendar in Python

Python has a built-in library to print a calendar directly, but you can also create your own implementation. This article covers both methods.

Method 1: Using the Built-in calendar Module

The calendar module provides functions to display calendars. Here's a simple example:

import calendar

year = int(input("Enter year: "))
month = int(input("Enter month: "))

# Print calendar for a specific month
print(calendar.month(year, month))

# Print calendar for the entire year
calendar.prcal(year)

Sample output:

Enter year: 2017
Enter month: 3
     March 2017
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

                                  2017

      January                   February                   March
...

You can adjust the first day of the week using setfirstweekday(). For example, to start weeks on Sunday:

calendar.setfirstweekday(6)  # Sunday is 6
calendar.prcal(2016)

Method 2: Custom Implementation

You can implement your own calendar printing function to understand the logic. The custom implementation includes the following helper functions:

  • is_leap(year): Determine if a year is a leap year.
  • month_days(year, month): Get the number of days in a given month.
  • total_days_since_1800(year, month): Calculate days elapsed since January 1, 1800.
  • first_day_of_month(year, month): Determine the day of the week for the first day of the month using Zeller's congruence.
  • print_month_title(year, month): Print the month's header.
  • print_month_body(year, month): Print the days of the month.

Here's the complete implementation:

def is_leap(year):
    """Return True if year is a leap year."""
    return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)

def month_days(year, month):
    if month in (1, 3, 5, 7, 8, 10, 12):
        return 31
    elif month in (4, 6, 9, 11):
        return 30
    elif is_leap(year):
        return 29
    else:
        return 28

def total_days_since_1800(year, month):
    """Calculate days from January 1, 1800 to the first of the given month."""
    days = 0
    for y in range(1800, year):
        days += 366 if is_leap(y) else 365
    for m in range(1, month):
        days += month_days(year, m)
    return days

def first_day_of_month(year, month):
    """Return the day of week of the first day of the month (0=Sunday, 1=Monday, ..., 6=Saturday)."""
    # Zeller's congruence for Gregorian calendar
    if month < 3:
        month += 12
        year -= 1
    q = 1  # day of month
    m = month
    J = year // 100
    K = year % 100
    h = (q + (13 * (m + 1)) // 5 + K + K // 4 + J // 4 + 5 * J) % 7
    # Convert h (0=Saturday, 1=Sunday, ..., 6=Friday) to our desired representation (0=Sunday, ..., 6=Saturday)
    return (h + 6) % 7

MONTH_NAMES = [
    "January", "February", "March", "April", "May", "June",
    "July", "August", "September", "October", "November", "December"
]

def month_name(month):
    return MONTH_NAMES[month - 1]

def print_month_title(year, month):
    print(f"{month_name(month)} {year}".center(45))
    print("-" * 45)
    print("  Sun  Mon  Tue  Wed  Thu  Fri  Sat")

def print_month_body(year, month):
    first_day = first_day_of_month(year, month)
    days = month_days(year, month)
    
    # Print leading spaces
    print(" " * (5 * first_day + 2), end="")  # 2 initial spaces, 5 per day
    
    for day in range(1, days + 1):
        print(f"{day:4d} ", end="")
        first_day += 1
        if first_day == 7:
            print()
            first_day = 0
            print("  ", end="")  # initial spaces for new line
    print()  # final newline

def print_calendar(year, month=None):
    if month is None:
        for m in range(1, 13):
            print_month_title(year, m)
            print_month_body(year, m)
            print()
    else:
        print_month_title(year, month)
        print_month_body(year, month)

# Example usage
if __name__ == "__main__":
    year = int(input("Enter year: "))
    month = int(input("Enter month: "))
    print_calendar(year, month)

In this custom implementation, we used Zeller's congruence to determine the first day of the month. The printing format uses a width of 5 characters per day, with Sunday as the first column. The function print_calendar can print a single month or a entire year.

Tags: python Calendar programming Exercise

Posted on Thu, 13 Aug 2026 16:08:34 +0000 by waynerooney