CALENDAR USING CLASSES C++

how do I find the first day, and how can I output the numbers of the calendar in the usual order as they're found on hard or virtual copies of calendar: Here is my code:

It's long, but as of now it works. The program has to keep its current format because the point is to know how to use classes. I need two things, print the days in order(columns and rows), and to find the first day to start printing the day correctly to match day, name day, and month(within the same columns and rows). Any help would be much appreciated.

This is an example of the output that I want to achieve regarding my question ONLY!!! Days and numbers should match the right DATE. e.g. if I say 7 / 4 / 2011; the program should out that the day is "MONDAY JULY 4, 2011" and the number on the calendar should match the acronym = ......"SUN""MON" "TUE"..........
___________________________________......" 3 " " 4 " " 5 "............

//example output(NOT actual output of my code)

          March
Sun Mon Tue Wed Thu Fri Sat
         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



Thanks in advance.

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//main cpp. file
#include <iostream>
#include <string>
#include <iomanip>
#include "extDateType.h"
//#include "chapter11.h"

using namespace std;

string extDateType::Months[12] = {"January", "February", "March", "April", 
                     "May", "June", "July", "August", "September", 
					 "October", "November", "December"};
void extDateType::setData(int Month, int day, int year)
{
   int i;

	 for(i = 0; i < 12; i++)
	    if(Months[i] == yMonth)
		  break;
	yMonth = Months[(i + Month) % 13];
	yDays = day;
	yYears = year;
}
string extDateType::getMonth() const
{
	return yMonth;
}
int extDateType::getDays() const
{
	return yDays;
}
int extDateType::getYear() const
{
	return yYears;
}
void extDateType::printDate() const
{
	cout << yMonth << " " << yDays << "," << yYears << endl;
	cout << " " << endl;
	cout << "This is the calendar of " << yYears << "." << endl;
	int i;
	string dayHeader= string("Sun ") + char(186) + " Mon " + char(186) + " Tue " + char(186) +
        " Wed " + char(186) + " Thu " + char(186) + " Fri " + char(186) + " Sat " + char(186);
    
	for(i = 0; i < 12; i++)
	if(Months[i] == yMonth)
	{
	  cout << yMonth <<", " << yYears << endl;
	  cout << dayHeader << endl;
	  
	}
    
	cout << "" << endl;
}
extDateType::extDateType(int Month, int day, int year)
{
	yMonth = Month;
	yDays = day;
	yYears = year;
}


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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//implementation file for extDateImp.h
#include <iostream>
#include <string>
#include <iomanip>
#include "extDateType.h"
//#include "chapter11.h"

using namespace std;

string extDateType::Months[12] = {"January", "February", "March", "April", 
                     "May", "June", "July", "August", "September", 
					 "October", "November", "December"};
void extDateType::setData(int Month, int day, int year)
{
   int i;

	 for(i = 0; i < 12; i++)
	    if(Months[i] == yMonth)
		  break;
	yMonth = Months[(i + Month) % 13];
	yDays = day;
	yYears = year;
}
string extDateType::getMonth() const
{
	return yMonth;
}
int extDateType::getDays() const
{
	return yDays;
}
int extDateType::getYear() const
{
	return yYears;
}
void extDateType::printDate() const
{
	cout << yMonth << " " << yDays << "," << yYears << endl;
	cout << " " << endl;
	cout << "This is the calendar of " << yYears << "." << endl;
	int i;
	string dayHeader= string("Sun ") + char(186) + " Mon " + char(186) + " Tue " + char(186) +
        " Wed " + char(186) + " Thu " + char(186) + " Fri " + char(186) + " Sat " + char(186);
    
	for(i = 0; i < 12; i++)
	if(Months[i] == yMonth)
	{
	  cout << yMonth <<", " << yYears << endl;
	  cout << dayHeader << endl;
	  
	}
    
	cout << "" << endl;
}
extDateType::extDateType(int Month, int day, int year)
{
	yMonth = Month;
	yDays = day;
	yYears = year;
}


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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
//implementation file for days(chapter11.h)

#include <iostream>
#include <string>
#include "chapter11.h"

;
using namespace std;


string dayType::weekDays[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};


void dayType::print() const
{
	cout << weekDay << " ";
}
string dayType::getDay() const
{
	 
	 return weekDay;
	
}
string dayType::prevDay() const
{	
	int i;
    
    for(i = 0; i < 7; i++)
	if (weekDays[i] == weekDay)
       break;
		weekDay == weekDays[(i - 3) % 7];
		
	return weekDay;
}
string dayType::nextDay() const
{
    int i; 

    for(i = 0; i < 7; i++)
   if (weekDays[i] == weekDay)
   break;
		weekDay == weekDays[(i + 2) % 7];
		
   
	return weekDay;
}

void dayType::setDay(string d)
{
	weekDay = d;
}
void dayType::addCalDay(int nDays)
{
	int i;

	for(i = 0; i < 7; i++)
	  if(weekDays[i] == weekDay)
		  break;
	weekDay = weekDays[(i + nDays) % 7];
}
	
dayType::dayType()
{
	weekDay = "Monday";
}
dayType::dayType(string d)
{
	weekDay = d;
}


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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include "dateType.h"
//#include "chapter11.h"

using namespace std;

void dateType::setDate(int month, int day, int year)
{


    if (year >= 1)
        dYear = year;
    else
        dYear = 1900;

    if (1 <= month && month <= 12)
        dMonth = month;
    else
        dMonth = 1;

    switch (dMonth)
    {
    case 1: 
    case 3: 
    case 5: 
    case 7:
	case 8: 
    case 10: 
    case 12: 
        if (1 <= day && day <= 31)
		
            dDay = day;
		    
		
        else
		
            dDay = 1;
		
        break;
	case 4: 
    case 6: 
	case 9: 
    case 11: 
        if (1 <= day && day <= 30)
		
            dDay = day;
		
		
		else
            dDay = 1;
        break;
	case 2: 
        if (isLeapYear())
		{
            if (1 <= day && day <= 29)
			
                dDay = day;
			    
			
            else
			
                dDay = 1;
			
        }
        else
        {
            if (1 <= day && day <= 28)
                dDay = day;
            else
                dDay = 1;
        }
    }
}

int dateType::getDay() const 
{
    return dDay;
}

int dateType::getMonth() const 
{
	
    return dMonth;
}

int dateType::getYear() const 
{
    return dYear;
}

bool dateType::isLeapYear()
{

    if (((dYear % 4 == 0) && (dYear % 100 != 0)) || dYear % 400 == 0)
        return true;
    else
        return false;
}

void dateType::printDate() const
{
    cout << dMonth << "-" << dDay << "-" << dYear;
}
	//constructor 
dateType::dateType(int month, int day, int year) 
{ 
    setDate(month, day, year);
}



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
#ifndef H_chapter11
#define H_chapter11
#include <iostream>
#include <string>
#include "dateType.h"
#include "extDateType.h"
using namespace std;

class dayType: public dateType, public extDateType
{
public:
	static string weekDays[7];
	void setDay(string d);
	void print() const;
    
	string getDay() const;
	string nextDay() const;
	string prevDay() const;
	//void addDay(int nDays);
	
	void addCalDay(int nDays);
    dayType();
	dayType(string d);

private:
	string weekDay;
}
#endif



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
#ifndef H_dateType
#define H_dateType
#include <iostream>


using namespace std;
 
class dateType 
{
public:
    void setDate(int month, int day, int year);
    
    int getDay() const;
    int getMonth() const;
    int getYear() const;
    void printDate() const;
	bool isLeapYear();
    dateType(int month = 1, int day = 1, int year = 1900);
private:
    int dMonth;      //variable to store the month
    int dDay;        //variable to store the day
    int dYear;       //variable to store the year
};
#endif



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

#ifndef H_extDateType
#define H_extDateType
#include <iostream>
using namespace std;

class extDateType
{
public:
	
	static string Months[12];
	void setData(int, int, int);
    string getMonth() const;
	int getDays() const;
	int getYear() const;

	void printDate() const;
    extDateType(int Month = 0, int day = 1, int year = 1900);

private:
	string yMonth;
	int yDays;
	int yYears;
};
#endif


Last edited on
This is an approach I once used though there may be other better ways. The minimum number of rows of weeks for a month is four for February in a non-leap year with February 1st on Sunday. The maximum is six for months with 30 or 31 days with the 1st starting on a Saturday, but in order to keep the months aligned in the output you need to treat all months as having six weeks. This approach uses a look-up table and a function that returns a pointer into an array that gives the starting place in the table.

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
namespace
{
	const int monthDays28[ 48 ] =
	{
		 0,  0,  0,  0,  0,  0,  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,  0,
		 0,  0,  0,  0,  0,  0,  0,
		 0,  0,  0,  0,  0,  0
	};

	const int monthDays29[ 48 ] =
	{
		 0,  0,  0,  0,  0,  0,  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,
		 0,  0,  0,  0,  0,  0,  0,
		 0,  0,  0,  0,  0,  0
	};

	const int monthDays30[ 48 ] =
	{
		 0,  0,  0,  0,  0,  0,  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,  0,  0,  0,  0,  0,  0,
		 0,  0,  0,  0,  0,  0
	};

	const int monthDays31[ 48 ] =
	{
		 0,  0,  0,  0,  0,  0,  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,  0,  0,  0,  0,  0,
		 0,  0,  0,  0,  0,  0
	};
}


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
const int* getStart42DayWindow( int year, int month )
{
	boost::gregorian::date d( year, month + 1, 1 );
	short daysInMonth = boost::gregorian::gregorian_calendar::end_of_month_day( year, month + 1 );
	short dayOfWeek   = d.day_of_week();
	short offset      = 6 - dayOfWeek;

	const int* p = 0;
	switch ( daysInMonth )
	{
	case 28 :
		p = monthDays28 + offset;
		break;

	case 29 :
		p = monthDays29 + offset;
		break;

	case 30 :
		p = monthDays30 + offset;
		break;

	case 31 :
		p = monthDays31 + offset;
		break;

	default :
		break;
	}
	return p;
}



Note that the unnamed namespace gives the arrays filescope so that any functions that use those arrays needs to be in the same code file. Also, I am using the boost date library in which the months are numbered from 1 to 12 whereas in my own code months run from 0 to 11. To output March, 2011 you would use code along these lines.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int year = 2011;
int month = 2;
const int* p = getStart42DayWindow( year, month );

for ( int week = 0; week < 6; ++week )
{
    for ( int day = 0; day < 7; ++day )
    {
        if ( *p == 0 )
        {
            // output spaces to get to the next column
        }
        else
        {
            std::cout << *p;
            // output spaces to get to the next column which may require an extra space
            // for the single digit days 1 to 9
        }
        std::cout << std::endl;
        ++p;
    }
}


Perhaps you will find the above code sketch useful as a starting point which you can modify for your own purposes.

I just need to add the days' numbers in rows and columns but I need them to be flexible so that depending on the year the days' number will change their order keeping always in mind the current day acronym column's order. This is a tough one, but I know there's a way. It's got to be. Thanks for the latest responses, but so far they do not accomplish the fact that I explained above in this particular message.

for example today is: July 4th 2011(Monday)

next year: July 4th 2012 will be on (Tuesday)

the year after will be: July 4th 2013 on (Wednesday)

and so on ........etc

Thanks again guys.
Last edited on
The code above is flexible and is independent of the year and month. Notice that the call to getStart42DayWindow( int year, int month ) takes both a year and a month. The only problematic parts are the use of the boost date library and outputting a full six rows for months that only need four or five rows, but I'll discuss how to fix that at the end of this post. Also note that in the arrays zero is a place holder that means "skip this column".

Let's trace through the code for July, 2011 to see how it works.

With month = 6 ( July ) and year = 2011 and stepping through getStart42DayWindow( int year, int month ):

line 4 creates a boost date d for July 1, 2011
line 5 initializes daysInMonth to 31
line 6 initializes dayOfWeek to 5 corresponding to Saturday ( day of the week runs 0-6 )
These are the only lines of code that use the boost date library.

line 6 sets up offset to tell us where to start in the array. Notice that all of the arrays begin with six zeroes. This corresponds to 6 blank days at the beginning of the month with the first of the month on Saturday. Suppose the first is on Friday. Then we only want five zeroes ( or blank days ) in the first week of the month which corresponds to starting one past the start of the array. For first of the month on Thursday we need four zeroes ( or blank days ) in the first week so we want to start two past the beginning of the array and so forth for the other days of the week that the first may fall on.

In the specific example we are tracing through since dayOfWeek is 5, offset will be 1.

line 8 declares the pointer that will ultimately be copied and returned. This pointer will point to the starting point within the appropriate array.

line 9 We now switch on daysInMonth to select the correct array, in our case monthDays31.

line 24 p = monthDays31 + offset; An array name used by itself without the brackets yields a pointer to the first element of the array. Adding offset which is equal to one in this example moves the pointer p to the second element of the array. Notice that this will leave five zeroes ( blank days) at the beginning of the month since the July 1, 2011 is Friday. Now once the calling code obtains the pointer returned from getStart42DayWindow( int year, int month ) it is only necessary to output 42 values in the array for six full weeks, interpreting a zero value as a blank day. The zeroes at the ending of the arrays are to make sure that calling code does not overrun the end of the array even for months that start on Saturday, that is, there will always be at least 42 elements in the array no matter where we start.

Below is the output code which I sketched above with more details filled in to get the sample output format you showed.

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
int year = 2011;
int month = 6;
const int* p = getStart42DayWindow( year, month );

for ( int week = 0; week < 6; ++week )
{
    std::cout << ' ';     // this is the indent under the Sun heading
    for ( int day = 0; day < 7; ++day )
    {
        if ( *p == 0 )
        {
            // output four spaces to get to the next column
           std::cout << "    ";
        }
        else
        {
            std::cout << *p;
            // output spaces to get to the next column which may require an extra space
            // for the single digit days 1 to 9
           std::cout << ( *p < 10 ? "   " : "  " );
        }
        ++p;
    }
    std::cout << std::endl;
}


If you don't want to output six full rows for months that only need four or five rows, one approach would be to initialize a variable lastDayOfMonth before both for loops and use a boolean isDone in the condition of the outer loop.

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
32
int year = 2011;
int month = 6;
const int* p = getStart42DayWindow( year, month );
bool isDone = false;
int lastDayOfMonth = 31; // you would need to call a function to get this value for the year and month

for ( int week = 0; week < 6 && !isDone; ++week )
{
    std::cout << ' ';     // this is the indent under the Sun heading
    for ( int day = 0; day < 7; ++day )
    {
        if ( *p == 0 )
        {
            // output four spaces to get to the next column
           std::cout << "    ";
        }
        else
        {
            std::cout << *p;
            // output spaces to get to the next column which may require an extra space
            // for the single digit days 1 to 9
           std::cout << ( *p < 10 ? "   " : "  " );
        }
        if ( *p == lastDayOfMonth )
        {
             isDone = true;
             break;
        }
        ++p;
    }
    std::cout << std::endl;
}


To remove the dependency on the boost date library you need to do two things in getStart42DayWindow()
1) initialize daysInMonth using your own function
2) write a function to initialize dayOfWeek to an ordinal number 0-6. The prototype of such a function could look something like this:
int getDayOfWeek( int year, int month, int day );
One approach to such a function is to start with a base day whose day of the week is known. Then write a helper function called dayDiff which calculates the number of days between a given date and the base date. Dividing this number modulo 7 and looking at the remainder tells you where you are in the week in relationship to the base date whose day off is known. If the remainder is zero it is the same day of the week as the base date. If the remainer is one it is one day later in the week and so forth.

The code for getStart42DayWindow() with the arrays has been tested before but the code snippet to output a month is just off the top of my head and has not been compiled or tested.
Topic archived. No new replies allowed.