Solved

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

Posted on 2003-12-04
19
463 Views
Last Modified: 2010-04-17
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 .
 


0
Comment
Question by:jdog_34
  • 10
  • 9
19 Comments
 
LVL 22

Accepted Solution

by:
cookre earned 290 total points
ID: 9876467
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
 
LVL 22

Expert Comment

by:cookre
ID: 9876531
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 Comment

by:jdog_34
ID: 9876770
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
 
LVL 22

Expert Comment

by:cookre
ID: 9877294
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 Comment

by:jdog_34
ID: 9877623
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
 
LVL 22

Expert Comment

by:cookre
ID: 9878128
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 Comment

by:jdog_34
ID: 9878215
Thanks again
0
 

Author Comment

by:jdog_34
ID: 9879045
I have one more question. In the last equation, do I need parens around anything or just leave it as is. Thanks.
0
 
LVL 22

Expert Comment

by:cookre
ID: 9879250
As is.
The outer-most parens are for the expression we take the modula 7 of.
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:jdog_34
ID: 9879431
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 Comment

by:jdog_34
ID: 9879440
Oh, is the day the day of the week that January 1st falls on but still will the month always be January?
0
 
LVL 22

Expert Comment

by:cookre
ID: 9879767
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 Comment

by:jdog_34
ID: 9881494
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
 
LVL 22

Expert Comment

by:cookre
ID: 9881822
You'll have to post your code.
0
 

Author Comment

by:jdog_34
ID: 9884829
// 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
 
LVL 22

Expert Comment

by:cookre
ID: 9885471
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 Comment

by:jdog_34
ID: 9887117
I'm not sure if this works, I tried it and I get some weird output, thanks though.
0
 
LVL 22

Expert Comment

by:cookre
ID: 9887172
I just ran a test and it worked fine.  Typo maybe?
0
 
LVL 22

Expert Comment

by:cookre
ID: 9887198
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

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
scoresAverage challenge 8 76
c# combobox autocomplete behavior 6 92
copyEndy  challenge 15 58
countPairs challenge 7 58
RIA (Rich Internet Application) tools are interactive internet applications which have many of the characteristics of desktop applications. The RIA tools typically deliver output either by the way of a site-specific browser or via browser plug-in. T…
This is an explanation of a simple data model to help parse a JSON feed
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now