C++, How to implement a calandar based on this input???

I am somewhat new to programming but I really love attacking new problems.  A recent project I am working on involve implementing a calendar based on this input:

1.) The year you want a calendar for, like say 1992, etc.
2.) The day of the week that January 1st falls on(represented by 0-6. (Tuesday = 2).

This is not a homework assignment as I am out of school and have been for a couple years.  I would really just love some hints and help on getting started on this problem. Here is what I know so far which is obvious information and are given with the problem in the book I purchased.

a.) Each successive month starts on the day of the week that follows the last day of the preceding month.
b.) Days of the week should be numbered 0-6 for Sunday through Saturday.
c.) Years that are divisible by four are leap years.

Here is a sample input and output:

INPUT
=======================================
What year do you want a calendar for?  1985

What day of the week does January 1st fall on (0-6)?  2

OUTPUT
=======================================

January
S   M   T   W   T   F   S
---------------------------
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

.....etc. with the following months to December for that year.

I hope somone can help a little with this so I can continue learning. Thanks .

Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Commented:
1) You don't have to ask for which day 1 Jan is because you can get that programmatically.

2) That extends to being able to programmatically find which day of the week any given date falls on. Hence,

3) It would be easier to build a routine to generate a single month calendar, then just call it 12 times.

4)  Keep calendar calulations seperate from calendar display.

5) To facilitate calendar, base everyting on a a 6x7 array, i.e., six 7-day weeks, initialized to zero, then filled with the day of month numbers:
Get day of week for the first of that month, determine the number of days in that month, then fill in the array.
To be fancy, use negative numbers to indicate day of month numbers for those portions of the previous and next months that would appear on that page - the calendar print routine could then ignore negatives or display them dimmer and/or smaller.

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Commented:
Leap years are divisible by four EXCEPT for those divisible by 100 but not 400.  Hence, 1900 was NOT a leap year, but 2000 was.

Also, you may want to put a bottom limit on the year.  The US adopted the Gregorian calendar in mid 18th century (Sep, 1753?), so earlier months won't render correctly.  Greece didn't adopt it until 1923.
0
Author Commented:
cookre, thanks a lot but I'm sure I understand what u mean by getting it programmatically.  Your tips have helped a lot.  If you can provide any small code segments, that would help a lot too but you have helped greatly already.  Can you maybe explain the last part about the negative number and how to get the day of the month the 1st falls on.  Thanks again.
0
Commented:
If you're using MFC, CTime::GetDayOfWeek get's you a DOW number for the specified date.

If you're not using MFC, you have to go through the extra hoop of converting a time_t date to a struct tm, the latter of which will have the corresponding DOW number.

Once you have a DOW for the first of the month, the rest is easy.

e.g:
// Initialize month
for (week=0; week<6; week++) for (day=0; day<7; day++) Month[week][day]=0;

// Fill in first week (Assume DOW=0...6)
DayOfMonth=1;
for (day=DOW; day<7; day++) Month[0][day]=DayOfMonth++;

// Fill in rest of month
for (week=1; week<6; week++)
for (day=0; day<7; day++)
{
if (DayOfMonth>NumberOfDaysInMonth) break;
Month[week][day]=DayOfMonth++;
}

What I meant by the fancy part:
Some monthly calendars will show the previous month's day of month numbers in the first row of the calendar if this month doesn't start on Sunday.  E.g.:
29  30   1   2   3   4   5

(same for the tail end of the last week)

To ease readibility, the previous and next month's day of month numbers are printer either small or dimmer than this month's.

Now, your print routine just prints out the numbers in the above constructed Month array in whatever format you want. As it stands right now, a zero indicates a day not in the current month.  However, you could use negative numbers to indicate previous and next month's numbers so the print routine could print them differently.

For example, Month for Dec 2003 without dealing with adjacent months would look like:
0,1,2,3,4,5,6
...
28,29,30,31,0,0,0
0,0,0,0,0,0,0

Dealing with adjacent months, it woud look like:
-30,1,2,3,4,5,6
...
28,29,30,31,-1,-2,-3
-4,-5,-6,-7,-8,-9,-10

This month also shows you one of the decisions you have to make:
How do you deal with week 5 and/or 6 if the current month has no days in those weeks?

If you're just printing numbers, no big deal.

If you're printing numbers in boxes, yes big deal.
0
Author Commented:
Wow, you are awesome. You will definitley be getting the points for this and I wish I could give you more. But, I am not using MFC. I am using Microsoft's Visual Studio 6.0 (C++).  How to I get the DOW, which I am assuming is the day of week that that January 1st lands on. Sorry, this might be a stupid question. Let me know and thanks a lot.
0
Commented:
Here's a generic DayOfWeek getter.  It returns 0-6 for Sun-Sat:

int DayOfWeek(int Year ,int Month ,int Day)
{
if (Month<3) {Month+=13; Year--;}
else          Month++;
return (  Day
+ 26*Month/10
+ Year
+ Year/4
- Year/100
+ Year/400
+ 6
) % 7;
}

This is good only for the Gregorian calendar, so remember the cautions above about old dates.
0
Author Commented:
Thanks again
0
Author Commented:
I have one more question. In the last equation, do I need parens around anything or just leave it as is. Thanks.
0
Commented:
As is.
The outer-most parens are for the expression we take the modula 7 of.
0
Author Commented:
Sorry to ask any more question s but I have one more.  The variables paet into the DayOfWeek function, what should their values be upon entering the function. Will the month always be January?I know I'm passing in a year like 1990, then a month?, and then day, what will month and day be?  Maybe just explain that a little more. Thanks again man.
0
Author Commented:
Oh, is the day the day of the week that January 1st falls on but still will the month always be January?
0
Commented:
Thats a general DOW finder - any date.

Returns the day of the week (0-6 Sun-Sat) for the specified year (4 digits>1753+/-), month(1-12), and day(1-31).

xmas02=DOW(2002,12,25);
EndAug1972=DOW(1972,8,31);
Begin04=DOW(2004,1,1);
0
Author Commented:
I got everything to work except for when I print out the calendar. The numbers don't line up and the 1st doesn't start on the right day of week. Like, for example this is the output for January 2001:

S  M   T  W  T   F  S
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

it should be:
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

if yo ucould help me here it woild be awesome, thanks again. I'm going to try and give you more points for this.
0
Commented:
You'll have to post your code.
0
Author Commented:
// Print each month in Calendar

PrintCalendar(i);  // i = 0-11

// NEED TO FIGURE OUT SPACING AND LINING UP NUMBERS IN EACH MONTH

dowBuffer = 0;    // Keeps track of when to go to next line
for(week = 0; week < 6; week++)
for(day = 0; day < 7; day++)
{
if (dowBuffer >= 7)
{
cout << endl;
dowBuffer = 0;
}

if(month[week][day] != 0 )
cout << month[week][day] << "  ";

else
cout <<  "   ";

dowBuffer++;

}

/////////////////////////////////////////////////////////////////////////////////////////////
void PrintCalendar(int i)
{
// Print Calendar Heading
switch( i)
{
case 0: cout << "January" << endl;
break;
case 1: cout << "February" << endl;
break;
case 2: cout << "March" << endl;
break;
case 3: cout << "April" << endl;
break;
case 4: cout << "May" << endl;
break;
case 5: cout << "June" << endl;
break;
case 6: cout << "July" << endl;
break;
case 7: cout << "August" << endl;
break;
case 8: cout << "September" << endl;
break;
case 9: cout << "October" << endl;
break;
case 10: cout << "November" << endl;
break;
case 11: cout << "December" << endl;
break;
}

cout << "S  M  T  W  T  F  S" <<  endl;
cout << "----------------------" << endl;

}

I think I need to use some sort of alignment function like  setprecision( ) or setw( ), I don't know. This is all I need though and everything else works awesome.  I was mainly trying to figure it out by trial and air. Here is a sample output of January 1999.

S  M  T  W  T  F  S
----------------------
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

Hopefully this helps.
0
Commented:
I'm presuming a fixed pitch font...

char TmpStr[5];
for (week=0; week<6; week++)
{
for (day=0; day<7; day++)
{
if (month[week][day]==0)
cout << "    ";  // 4 spaces
else
sprintf(Tmpstr,"%4d",month[week][day]);
cout << TmpStr;
}
cout << endl;
}
0
Author Commented:
I'm not sure if this works, I tried it and I get some weird output, thanks though.
0
Commented:
I just ran a test and it worked fine.  Typo maybe?
0
Commented:
Oops.  The test worked, but it wasn't a good test.

for (week=0; week<6; week++)
{
for (day=0; day<7; day++)
{
if (month[week][day]==0)
cout << "    ";  // 4 spaces
else
{       <------------------------------------------------------------------
sprintf(Tmpstr,"%4d",month[week][day]);
cout << TmpStr;
}       <------------------------------------------------------------------
}
cout << endl;
}
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Programming

From novice to tech pro — start learning today.