Kelick Tech Hub

Build, learn & keep up — tech, Linux & sports news included.

C++ Calendar Generator Project

Beginner•Half a day•date math, loops, formatting

Print a correctly aligned calendar for any month and year.

Share on X

What you will build

Type a month and year, get a neat wall-calendar grid. The puzzle is calendrical: you must work out which weekday the 1st falls on (leap years included) and pad the first row. It's pure logic and formatting — no libraries doing the work for you.

What you will learn

Feature checklist

Starter code

#include <iostream>
#include <iomanip>

bool isLeap(int y) { return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0; }

int daysInMonth(int m, int y) {
    static const int days[] = {31,28,31,30,31,30,31,31,30,31,30,31};
    return (m == 2 && isLeap(y)) ? 29 : days[m - 1];
}

// Zeller's congruence: 0 = Saturday ... 6 = Friday
int firstWeekday(int m, int y) {
    if (m < 3) { m += 12; --y; }
    int k = y % 100, j = y / 100;
    int h = (1 + 13 * (m + 1) / 5 + k + k / 4 + j / 4 + 5 * j) % 7;
    return (h + 6) % 7; // convert so 0 = Sunday
}

int main() {
    int m = 10, y = 2026;
    int start = firstWeekday(m, y);
    std::cout << " Su Mo Tu We Th Fr Sa\n";
    for (int i = 0; i < start; ++i) std::cout << "   ";
    for (int d = 1; d <= daysInMonth(m, y); ++d) {
        std::cout << std::setw(3) << d;
        if ((start + d) % 7 == 0) std::cout << "\n";
    }
    std::cout << "\n";
}

Full walkthrough

Step 1: Write isLeap() — the rule everything depends on

A year is a leap year if it is divisible by 4, except century years, which must be divisible by 400: (y % 4 == 0 && y % 100 != 0) || y % 400 == 0. So 2024 is a leap year, 1900 was not, 2000 was. Get this one line wrong and every February you ever print is wrong.

Step 2: Build daysInMonth() on top of it

A static table {31,28,31,30,31,30,31,31,30,31,30,31} answers every month except February in a leap year, which returns 29. Taking the year as a parameter (not just the month) is the whole point — daysInMonth(2, 2024) and daysInMonth(2, 2023) must be able to disagree.

int daysInMonth(int m, int y) {
    static const int days[] = {31,28,31,30,31,30,31,31,30,31,30,31};
    return (m == 2 && isLeap(y)) ? 29 : days[m - 1];
}

Step 3: Find the weekday of the 1st with Zeller's congruence

firstWeekday(m, y) uses Zeller's formula: January and February are counted as months 13 and 14 of the PREVIOUS year (that is why the code does m += 12 and --y), then a mix of divisions by 4 and 100 extracts the weekday. The starter converts Zeller's Saturday-first result with (h + 6) % 7 so 0 = Sunday, matching the printed header.

Step 4: Print the header and the leading blanks

Print ' Su Mo Tu We Th Fr Sa' then start empty cells: for (i = 0; i < start; ++i) print three spaces each. Those blanks are what push the 1st under the correct weekday column. Every column is exactly 3 characters wide — that fixed width is the entire layout system.

Step 5: Print the days with setw and wrap weekly

Each day prints with std::setw(3) from <iomanip>. After printing day d, if (start + d) % 7 == 0 the week is complete, so print a newline. Notice the wrap test uses start + d — the day's position in the grid — not just d % 7; forgetting the start offset misaligns every row after the first.

for (int d = 1; d <= daysInMonth(m, y); ++d) {
    std::cout << std::setw(3) << d;
    if ((start + d) % 7 == 0) std::cout << "\n";
}

Step 6: Let the user choose month and year

The starter hard-codes October 2026 so you can verify the layout; the finished program prompts for month and year and validates 1–12 for the month. Verify October 2026 by hand: the 1st is a Thursday, so four blank cells precede it, and the month has 31 days.

Step 7: Add the whole-year view

For the checklist's year option, loop m from 1 to 12, print the month name above each grid, and reuse the exact same printing code — if you copied the code instead of calling it, this is your sign to refactor it into a printMonth(m, y) function first.

Common mistakes

Compile and run

g++ -std=c++17 -o calendar calendar.cpp

Sample run

$ ./calendar
Month (1-12):
> 10
Year:
> 2026
 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
$ ./calendar
Month (1-12):
> 2
Year:
> 2024
 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

Try it in your browser

No browser demo is included for this project. Build the C++ version below — that is the real program.

Related Beginner projects

← All 60 projects · Classic site (Learn & Sandbox)

Download Fake GPS