C++: Calendar

Bjarne-stroustrup
 

Create a routine that will generate a text calendar for any year. Test the calendar by generating a calendar for the year 1969, on a device of the time. Choose one of the following devices:

  • A line printer with a width of 132 characters.
  • An IBM 3278 model 4 terminal (80×43 display with accented characters). Target formatting the months of the year to fit nicely across the 80 character width screen. Restrict number of lines in test output to 43.

(Ideally, the program will generate well-formatted calendars for any page width from 20 characters up.)

Kudos (κῦδος) for routines that also correctly transition from Julian to Gregorian calendar in September 1752.

This task is inspired by Real Programmers Don’t Use PASCAL by Ed Post, Datamation, volume 29 number 7, July 1983.

THE REAL PROGRAMMER'S NATURAL HABITAT
"Taped to the wall is a line-printer Snoopy calender for the year 1969."

For further Kudos see task CALENDAR, where all code is to be in UPPERCASE.

For economy of size, do not actually include Snoopy generation in either the code or the output, instead just output a place-holder.

For other calendar-related tasks, see Five weekends.

#include <windows.h>
#include <iostream>

//--------------------------------------------------------------------------------------------------
using namespace std;


//--------------------------------------------------------------------------------------------------
class calender
{
public:
	void drawCalender( int y )
	{
		year = y;
		for( int i = 0; i < 12; i++ )
		firstdays[i] = getfirstday( i );

		isleapyear();
		build();
	}

private:
	void isleapyear()
	{
		isleap = false;

		if( !( year % 4 ) )
		{
			if( year % 100 ) isleap = true;
			else if( !( year % 400 ) ) isleap = true;
		}
	}

	int getfirstday( int m )
	{
		int y = year;

		int f = y + 1 + 3 * m - 1;
		m++;
		if( m < 3 ) y--;
		else f -= int( .4 * m + 2.3 );

		f += int( y / 4 ) - int( ( y / 100 + 1 ) * 0.75 );
		f %= 7;

		return f;
	}

	void build()
	{
		int days[] = { 31, isleap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		int lc = 0, lco = 0, ystr = 7, start = 2, fd = 0, m = 0;
		HANDLE h = GetStdHandle( STD_OUTPUT_HANDLE );
		COORD pos = { 0, ystr };
		draw();

		for( int i = 0; i < 4; i++ )
		{
			for( int j = 0; j < 3; j++ )
			{
				int d = firstdays[fd++], dm = days[m++];
				pos.X = d * 3 + start;
				SetConsoleCursorPosition( h, pos );

				for( int dd = 0; dd < dm; dd++ )
				{
					if( dd < 9 ) cout << 0 << dd + 1 << " ";
					else cout << dd + 1 << " ";

					pos.X += 3;
					if( pos.X - start > 20 )
					{
						pos.X = start; pos.Y++;
						SetConsoleCursorPosition( h, pos );
					}
				}

				start += 23;
				pos.X = start; pos.Y = ystr;
				SetConsoleCursorPosition( h, pos );
			}
			ystr += 9; start = 2;
			pos.Y = ystr;
		}
	}

	void draw()
	{
		system( "cls" );
		cout << "+--------------------------------------------------------------------+" << endl;
		cout << "|                              [SNOOPY]                              |" << endl;
		cout << "|                                                                    |" << endl;
		cout << "|                             == " << year << " ==                             |" << endl;
		cout << "+----------------------+----------------------+----------------------+" << endl;
		cout << "|       JANUARY        |       FEBRUARY       |         MARCH        |" << endl;
		cout << "| SU MO TU WE TH FR SA | SU MO TU WE TH FR SA | SU MO TU WE TH FR SA |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "+----------------------+----------------------+----------------------+" << endl;
		cout << "|        APRIL         |          MAY         |         JUNE         |" << endl;
		cout << "| SU MO TU WE TH FR SA | SU MO TU WE TH FR SA | SU MO TU WE TH FR SA |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "+----------------------+----------------------+----------------------+" << endl;
		cout << "|         JULY         |        AUGUST        |       SEPTEMBER      |" << endl;
		cout << "| SU MO TU WE TH FR SA | SU MO TU WE TH FR SA | SU MO TU WE TH FR SA |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "+----------------------+----------------------+----------------------+" << endl;
		cout << "|        OCTOBER       |       NOVEMBER       |       DECEMBER       |" << endl;
		cout << "| SU MO TU WE TH FR SA | SU MO TU WE TH FR SA | SU MO TU WE TH FR SA |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "|                      |                      |                      |" << endl;
		cout << "+----------------------+----------------------+----------------------+" << endl;
	}

	int firstdays[12], year;
	bool isleap;
};
//--------------------------------------------------------------------------------------------------
int main( int argc, char* argv[] )
{
	int y;
	calender cal;

	while( true )
	{
		system( "cls" );
		cout << "Enter the year( yyyy ) --- ( 0 to quit ): "; 
		cin >> y;
		if( !y ) return 0;

		cal.drawCalender( y );
		cout << endl << endl << endl << endl << endl << endl << endl << endl;

		system( "pause" );
	}
	return 0;
}
//--------------------------------------------------------------------------------------------------

Output:

+--------------------------------------------------------------------+
|                              [SNOOPY]                              |
|                                                                    |
|                             == 1969 ==                             |
+----------------------+----------------------+----------------------+
|       JANUARY        |       FEBRUARY       |         MARCH        |
| SU MO TU WE TH FR SA | SU MO TU WE TH FR SA | SU MO TU WE TH FR SA |
|          01 02 03 04 |                   01 |                   01 |
| 05 06 07 08 09 10 11 | 02 03 04 05 06 07 08 | 02 03 04 05 06 07 08 |
| 12 13 14 15 16 17 18 | 09 10 11 12 13 14 15 | 09 10 11 12 13 14 15 |
| 19 20 21 22 23 24 25 | 16 17 18 19 20 21 22 | 16 17 18 19 20 21 22 |
| 26 27 28 29 30 31    | 23 24 25 26 27 28    | 23 24 25 26 27 28 29 |
|                      |                      | 30 31                |
+----------------------+----------------------+----------------------+
|        APRIL         |          MAY         |         JUNE         |
| SU MO TU WE TH FR SA | SU MO TU WE TH FR SA | SU MO TU WE TH FR SA |
|       01 02 03 04 05 |             01 02 03 | 01 02 03 04 05 06 07 |
| 06 07 08 09 10 11 12 | 04 05 06 07 08 09 10 | 08 09 10 11 12 13 14 |
| 13 14 15 16 17 18 19 | 11 12 13 14 15 16 17 | 15 16 17 18 19 20 21 |
| 20 21 22 23 24 25 26 | 18 19 20 21 22 23 24 | 22 23 24 25 26 27 28 |
| 27 28 29 30          | 25 26 27 28 29 30 31 | 29 30                |
|                      |                      |                      |
+----------------------+----------------------+----------------------+
|         JULY         |        AUGUST        |       SEPTEMBER      |
| SU MO TU WE TH FR SA | SU MO TU WE TH FR SA | SU MO TU WE TH FR SA |
|       01 02 03 04 05 |                01 02 |    01 02 03 04 05 06 |
| 06 07 08 09 10 11 12 | 03 04 05 06 07 08 09 | 07 08 09 10 11 12 13 |
| 13 14 15 16 17 18 19 | 10 11 12 13 14 15 16 | 14 15 16 17 18 19 20 |
| 20 21 22 23 24 25 26 | 17 18 19 20 21 22 23 | 21 22 23 24 25 26 27 |
| 27 28 29 30 31       | 24 25 26 27 28 29 30 | 28 29 30             |
|                      | 31                   |                      |
+----------------------+----------------------+----------------------+
|        OCTOBER       |       NOVEMBER       |       DECEMBER       |
| SU MO TU WE TH FR SA | SU MO TU WE TH FR SA | SU MO TU WE TH FR SA |
|          01 02 03 04 |                   01 |    01 02 03 04 05 06 |
| 05 06 07 08 09 10 11 | 02 03 04 05 06 07 08 | 07 08 09 10 11 12 13 |
| 12 13 14 15 16 17 18 | 09 10 11 12 13 14 15 | 14 15 16 17 18 19 20 |
| 19 20 21 22 23 24 25 | 16 17 18 19 20 21 22 | 21 22 23 24 25 26 27 |
| 26 27 28 29 30 31    | 23 24 25 26 27 28 29 | 28 29 30 31          |
|                      | 30                   |                      |
+----------------------+----------------------+----------------------+

SOURCE

Content is available under GNU Free Documentation License 1.2.