×

Search anything:

Calendar in C++

C++

Binary Tree book by OpenGenus

Open-Source Internship opportunity by OpenGenus for programmers. Apply now.

We are going to discuss how we can make a Gregorian calendar of a specific year using C++. It's also known as new style calendar. It was named after Pope Gregory XIII who introduced this in 1582 as a reform of the Julian calendar, which was earlier being used since 45 BC. It was later adopted by different countries, and now it is the most widely used calendar in the world.

Julian calender got replaced, to correct the inaccuracy. The Julian calendar had leap year every four years, but this caused an overestimation of a year by about 11 minutes and 14 seconds. This caused many problems, the main one was that it caused the seasons to drift away. So the Gregorian calendar addressed this by making leap years less frequent, it changed the rule to be a leap year. In Gregorian calendar for a year which is divisible by 100cannot be a leap year, except for those divisible by 400. Thats why the year 1900 was not a leap year but the year 2000 was!

Under Gregorian calendar we have 12 months, from January to December, each of them have 30 or 31 days, except for February, which has 28 days, with an additional day added to it every 4 years.

Table of Contents
Click here to see the program related to this article.

  • Features & Requirements
  • Implementation Details
  • Working
  • Output
  • Conclusion

Features & Requirements

The features of this calender program is that it produces the accurate calender of a given year along with proper color gradings.

  • Like the year and the week days are denoted with golden color.
  • Past dates are denoted with red color.
  • The future dates, days and months have white color.
  • The current day and month is denoted with green color.
  • The calendar have a neat layout and is organized.

The requirements are a system which has GCC compiler to compile the C++ code.

Implementation Details

Before we get on to the working there are some terms we need to familiarize.

  • std::cin.fail(): It is a function which belongs to the standard library in C++. This function returns true when ever the input failure occurs. Here in this program we are using it to confirm the user input is an integer. Here if it fails we will break out of the loop.
  • time_t: In C++ we have time() which returns the current calender time as an object of type time_t. So its the simplest data type used to represent simple calendar time. It can be an integer or a floating-point type.
  • localtime(): Its a function defined in the ctime header file. It will convert the provided time to local time. It accepts a pointer to time_t object. It returns a pointer to a tm object if it was successful, else it would give a null pointer exception.
  • tm: It is a structure type, and it holds the date and time in the form of a C structure. The structure of tm and the elements it holds:
    struct tm {
     int tm_sec;   // seconds of minutes from 0 to 61
     int tm_min;   // minutes of hour from 0 to 59
     int tm_hour;  // hours of day from 0 to 24
     int tm_mday;  // day of month from 1 to 31
     int tm_mon;   // month of year from 0 to 11
     int tm_year;  // year since 1900
     int tm_wday;  // days since sunday
     int tm_yday;  // days since January 1st
     int tm_isdst; // hours of daylight savings time
    }
    
  • Zeller's Congruence: It is an algorithm developed by Christian Zeller in 1887 to calculate the first day of the week for any given date. It needs the year, month and day of the date and then calculates a number that corresponds to the day of the week, here Sunday is represented by 0 and all the way to Saturday by 6. Here in our program we are using a simplified version which only considers the year and uses modular arithmetic to determine the first day of January for the given year.

Working

So lets start from the int main(). Here we initialize an integer variable, and then we enter into an infinite while loop. Inside the while loop we asks the user to enter a year, to print the calendar for that particular year, and if the user wishes to quit they can enter anything other than an integer to stop the program.
We achieve this by using cin.fail() which as we discussed earlier will return true if the input failure occurs. When this happens the break statement executes and the loop is broken which will end the program. The following demonstrates the code.

int main()
{
    int year;
    while (1)
    {
        cout << "------------------------------------------------" << endl;
        cout << "Enter a year or type anything else to quit: ";
        cin >> year;
        cout << "------------------------------------------------" << endl;
        if (std::cin.fail())
            break;
        printCalendar(year);
    }

    return 0;
}

After getting the input we will call the printCalendar() and pass the input year to the function. Inside the function we will first initialize all the variables required.

First we will create a monthDays[] array of integer type and it will hold all the values of number of days of each month for the entire year. Then we will create another array monthList[] of string type, and here we will store all the 12 months in a year. As we said earlier, now we will use the time(0) function, which returns the current calender time as an object of type time_t. Now we will use localtime() in the returned object and store it in a pointer of type tm. As demonstrated by the below code.

int monthDays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    string monthList[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};

    time_t ttime = time(0);
    tm *local_time = localtime(&ttime);

Now we will create the current year, month, day variables from the tm variable. We will add 1900 to the year present in local_time because it will contain the number of years after 1900. The months inside it would start from 0 and thats why we add a 1 to it. In the end we will take the day value too.

    int current_year = 1900 + local_time->tm_year;
    int current_month = local_time->tm_mon + 1;
    int current_day = local_time->tm_mday;

Now we will first print the calender title with the requested year. Then we will calculate the starting day and the amount of spaces we should leave for the first month of the year using the formula startingGap = (tempY + tempY / 4 - tempY / 100 + tempY / 400 + 1) % 7; which is based on Zeller's congruence. The following code demonstrated it.

cout << " -----------------------------------" << endl;
    cout << "\033[1;33m"
         << "           Calendar - " << year
         << "\033[0m" << endl;
    cout << " -----------------------------------" << endl;

    int days;
    int startingGap;

    int tempY = year - 1;
    startingGap = (tempY + tempY / 4 - tempY / 100 + tempY / 400 + 1) % 7;

Now we will create a loop to iterate through the 12 months of the year. When i==1 we will check if the year is a leap year or not using the condition which we mentioned in the introduction. We will look whether the given year is divisible by 400 or divisible by 4 but not by 100. In that process we will assign the days variable with the value of that particular month. Then with if statements we will check if that year and the current month is equal, if yes we will print it in green. Similar condition is used on the days, weekdays and weekends are given different color, we use it on dates to check whether its past, today or the future dates and colors are given to each of them accordingly. Now we have a for loop to leave the required number of gap in the starting of the month. We did the calculation for the first month and for the second month onwards we use a variable k which is used to count the number of gaps required for the next month. When k is equal to 7 its given zero to reset and in the end we give the value of k to startingGap variable so that we could leave required gap for the next month starting date. The following code demonstrates it all.

for (int i = 0; i < 12; i++)
    {
        if ((year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) && i == 1)
            days = 29;
        else
            days = monthDays[i];

        cout << endl;
        if (year == current_year && current_month == i + 1)
        {
            cout << "\033[1;1;32m"
                 << "  ------------" << monthList[i] << "-------------"
                 << "\033[0m" << endl;
        }
        else if (year < current_year || (year == current_year && i + 1 < current_month))
        {
            cout << "\033[31m"
                 << "  ------------" << monthList[i] << "-------------"
                 << "\033[0m" << endl;
        }
        else
        {
            cout << "  ------------" << monthList[i] << "-------------"
                 << endl;
        }

        if (year < current_year || (year == current_year && i + 1 <= current_month))
        {
            cout << "\033[35m"
                 << "  Sun"
                 << "\033[0m";
            cout << "\033[1;33m"
                 << "  Mon  Tue  Wed  Thu  Frid";
            cout << "\033[35m"
                 << "  Sat"
                 << "\033[0m" << endl;
        }
        else
        {
            cout << "  Sun  Mon  Tue  Wed  Thu  Fri  Sat" << endl;
        }
        int k;
        for (k = 0; k < startingGap; k++)
            cout << "     ";

        for (int j = 1; j <= days; j++)
        {
            k++;
            if (year == current_year && current_month == i + 1 && current_day == j)
            {
                cout << "\033[1;1;32m" << setw(5) << j << "\033[0m";
            }
            else if (year < current_year || (year == current_year && i + 1 < current_month) || (year == current_year && i + 1 == current_month && j < current_day))
            {
                cout << "\033[31m" << setw(5) << j << "\033[0m";
            }
            else
            {
                cout << setw(5) << j;
            }
            if (k > 6)
            {
                k = 0;
                cout << endl;
            }
        }
        if (k)
            cout << endl;
        startingGap = k;
    }

After printing the calender it returns and that execution gets completed and the program will ask the user for the next input.

Output

The program was ran on 21st February 2023 and that date is indicated by green color, past dates by red and future by white.

output-1

*The image is a cropped one, so that it fits into the article properly. The rest of the months from June to December is printed in white color as it is for all the future months.

Conclusion

By the end of this article at OpenGenus, you would have got a complete idea on how to make a calender in C++. This program is a console application and can be improved in a lot of different ways, like to have a good GUI and transforming it into a calendar application is indeed one of the options.

Calendar in C++
Share this