Calendar problems

I can get my calendar to get most days correct, except February leap years. It's something with my computeOffset. Anyone see the problem?

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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#include <iostream>
#include <iomanip>
using namespace std;

int getMonth()
{
   int month;

   cout << "Enter a month number: ";
   cin >> month;

   while ( month < 1 || month > 12)
   {
      cout << "Month must be between 1 and 12.\n"
           << "Enter a month number: ";
      cin >> month;
   }

   return month;
}

int getYear()
{
   int year;

   cout << "Enter year: ";
   cin >> year;

   while ( year < 1753)
   {
      cout << "Year must be 1753 or later.\n"
           << "Enter year: ";
      cin >> year;
   }
   return year;
}


bool isLeapYear(int year, int month)
{
   if ((year % 4 == 0 && year % 100 != 0 && month != 1)
       || (year % 400 == 0))
      return true;
   else
      return false;
}

int computeNumberOfDays(int month, int year)
{
   if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8
      || month == 10 || month == 12)
      return 31;
   else if (month == 2 && isLeapYear(year, month))
      return 29;
   else if (month == 2)
      return 28;
   else if (month == 4 || month == 6 || month == 9 || month == 11)
      return 30;
}

/**********************************************************************
 * Will prompt for and save the offset
 ***********************************************************************/
int computeOffset(int month, int year)
{
   int offset = 0;
   int count = year - 1753;
   int addYear = year;

   for (int addYear = 0; addYear < count; addYear++)
   {
      offset = (offset + 365 + isLeapYear(year, month)) % 7;
      year--;
   }
   for (int addMonth = 1; addMonth < month; addMonth++)
   offset = (offset + computeNumberOfDays(addMonth, addYear)) % 7;

   return offset;
}


void displayOffset(int offset)
{
   if (offset == 0)
      cout << setw(8)  << "1";
   else if (offset == 1)
      cout << setw(12) << "1";
   else if (offset == 2)
      cout << setw(16) << "1";
   else if (offset == 3)
      cout << setw(20) << "1";
   else if (offset == 4)
      cout << setw(24) << "1";
   else if (offset == 5)
      cout << setw(28) << "1";

}


void displayCalendar(int numberOfDays, int offset, int month, int year)
{
   int spaces = 0;
   int date = 1;

   cout << endl;

   if (month == 1)
      cout << "January";
   else if (month == 2)
      cout << "February";
   else if (month == 3)
      cout << "March";
   else if (month == 4)
      cout << "April";
   else if (month == 5 )
      cout << "May";
   else if (month == 6 )
      cout << "June";
   else if (month == 7 )
      cout << "July";
 else if (month == 8 )
      cout << "August";
   else if (month == 9 )
      cout << "September";
   else if (month == 10 )
      cout << "October";
   else if (month == 11 )
      cout << "November";
   else if (month == 12 )
      cout << "December";

   cout << ", " << year << endl;
   cout << "  Su  Mo  Tu  We  Th  Fr  Sa" << endl;

   while (numberOfDays >= date)
   {
      if (offset < 6)
      {
         displayOffset(offset);
         date = 2;
         spaces = (offset * 4) + 8;
         offset = 6;
      }


      while (spaces < 28 && (numberOfDays >= date))
      {
         if (date < 10)
            cout << "   " << date;
         else
            cout << "  " << date;

         date += 1;
         spaces += 4;
      }
      cout << endl;
      spaces = 0;
   }
}

int main()
{
   int month = getMonth();
   int year = getYear();
   int numberOfDays = computeNumberOfDays(month, year);
   int offset = computeOffset(month, year);

   displayCalendar(numberOfDays, offset, month, year);

   return 0;
}

Last edited on
The first thing is this:

bool isLeapYear(int year, int month)

A leap year does not depend on the month. It only affects the month > 1.
I had the month in there because otherwise it would affect January
It shouldn't affect the month. What you do is the following:

Q: Is it a leap year?
A: Basically yes, but it is january so no.
I tried it without month and it didn't help. Still has the same issue of it not reading February correctly, and now it also doesn't register January correctly.
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
#include <iostream>
#include <iomanip>
#include <cstdlib>

bool isLeapYear(int year) {
    return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}

int daysInMonth(int year, int month) {
    if (month == 4 || month == 6 || month == 9 || month == 11)
        return 30;
    if (month == 2)
        return isLeapYear(year) ? 29 : 28;
    return 31;
}

// Jan 1, 1753 was a monday (offset 1)
int computeOffset(int year, int month) {
    int a = (year - 1753) /   4;
    int b = (year - 1701) / 100;
    int c = (year - 1601) / 400;
    int leap_years = a - b + c;
    int offset = (1 + year - 1753 + leap_years) % 7;
    for (int m = 1; m < month; m++)
        offset = (offset + daysInMonth(year, m)) % 7;
    return offset;
}

void displayCalendar(int year, int month) {
    const char *month_names[] = {
        "January","February","March","April","May","June",
        "July","August","September","October","November","December"};
    int numberOfDays = daysInMonth(year, month);
    int pos = computeOffset(year, month) + 1;
    std::cout << month_names[month-1] << ", " << year << '\n';
    std::cout << "  Su  Mo  Tu  We  Th  Fr  Sa\n";
    std::cout << std::setw(pos * 4)  << 1;
    for (int date = 2; date <= numberOfDays; ) {
        if (pos++ % 7 == 0) std::cout << '\n';
        std::cout << std::setw(4) << date++;
    }
    std::cout << '\n';
}

int main(int argc, char **argv) {
    if (argc != 3) {
        std::cerr << "Usage: mycal YEAR MONTH\n";
        return 1;
    }
    int year = atoi(argv[1]), month = atoi(argv[2]);
    if (year < 1753) {
        std::cerr << "Error: YEAR must be greater than 1752\n";
        return 1;
    }
    if (month < 1 || month > 12) {
        std::cerr << "Error: MONTH must be from 1 to 12\n";
        return 1;
    }
    displayCalendar(year, month);
}

Last edited on
I appreciate the code, but as a first semester coder I have no clue what most of that stuff means. I don't want a new code. If someone could help me figure out how to change the offset for leap year February by - 1 that's all I need. I have tried to offset -=1 while month == 2 and isLeapYear(year,month) but it doesn't seem to change anything at all.
It's just your code rewritten. isLeapYear and daysInMonth have been corrected (I may have renamed a thing or two, and I reordered the parameters putting year first). The offset calculation has been simplified and corrected and displayCalendar was simplified, too. The only novel thing is taking input from the command line so that it's easier to test. Just forget about that if you want. I think if you look at the code more closely you'll see that it's pretty simple.

What day does your calendar start on for Jan 1, 2000 ? (should be Sat)
What about Jan 1, 2020? (should be Wed)
https://www.timeanddate.com/calendar/?year=2020&country=1
I found the problem. I needed to subract one to the offest if it is a February and a leapyear, but the problem i was running into was the year was being subtracted, so when it would test the year, it was no longer a leap year.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int computeOffset(int month, int year)
{
   int offset = 0;
   int count = year - 1753;
   int addYear = year;
   int origYear = year;

   for (int addYear = 0; addYear < count; addYear++)
   {
      offset = (offset + 365 + isLeapYear(year, month)) % 7;
      year--;
   }
   if ( month == 2 && isLeapYear(origYear,month))
      offset -= 1;

   for (int addMonth = 1; addMonth < month; addMonth++)
      offset = (offset + computeNumberOfDays(addMonth, year)) % 7;

   return offset;
}
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
*    Brother Foushee, CS124
* Author:
*    Braxton Meyer
* Summary:
*    This program
*
*
*    Estimated:  6.0 hrs
*    Actual:     0.0 hrs
*      The most difficult part was
*
*
************************************************************************/

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;


char readFile(char fileName[], char board[])
{
   ifstream fin(fileName);
   if(fin.fail())
   {
      cout << "yo this be bad" << fileName << endl;
      return -1;
   }
   for (int i = 0; !fin.eof(); i++)
   {
      fin >> board[i];
      // if (board[i] == '0')
      // board[i] = ' ';
   }
   fin.close();
   return 0;
}

void saveQuit(char board[])
{
   char save;
   cout << "What file would you like to write your board to: ";
   cin >> save;
   //for (int i = 0; i < 2; i++)
   //{
   int i = 0;
      char * pboard;
      pboard = &board[i];
      ofstream fout("save.txt", ios::trunc);
      fout << pboard;
      fout.close();
      //}
   return;
}

void showValues()
{
   return;
}

void editSquare(char board[])
{
   cout << "What are the coordinates of the square: ";
   char coordinates[1];
   cin >> coordinates;
   cout << coordinates[0];
   return;
}

void display(char board[])
{
   cout << "\n   A B C D E F G H I\n";
   int j = 0;
   for (int i = 0; i < 9; i++)
   {
      if ((i % 3) == 0 && i != 0)
         cout << "   -----+-----+-----\n";
      cout << i + 1 << "  ";
      bool newRow = true;
      while ( j < (9 + (i * 9)))
      {
         if (newRow == false)
            cout << "|";
         //spot 1
         if (board[j] == '0')
            cout << "  ";
         else
            cout << board[j] << " ";
         //spot 2
         if (board[j + 1] == '0')
            cout << "  ";
         else
            cout << board[j + 1] << " ";
         //spot 3
         if (board[j + 2] == '0')
            cout << " ";
         else
            cout << board[j + 2];
         newRow = false;

         j += 3;
      }
      cout << endl;
   }
   return;
}

void displayOptions()
{
   cout << "Options:\n"
        << "   ?  Show these instructions\n"
        << "   D  Display the board\n"
        << "   E  Edit one square\n"
        << "   S  Show the possible values for a square\n"
        << "   Q  Save and Quit\n";
}

int interact(char board[])
{
   char input;
   cin >> input;
   switch(input)
   {
      case '?':
         displayOptions();
         break;
      case 'D':
         display(board);
         break;
      case 'E':
         editSquare(board);
         break;
      case 's':
      case 'S':
         break;
      case 'q':
      case 'Q':
         saveQuit(board);
         return -1;
         break;
   }
   return 0;
}
/**********************************************************************
* main reads the list, determines the speed of the searches, and outputs
* the results.
***********************************************************************/
int main()
{
   char fileName[256];
   cout << "Where is your board located? ";
   cin >> fileName;
   char board[81];
   readFile(fileName, board);
   displayOptions();
   display(board);
   int choice = 0;
   while (choice != -1)
      choice = interact(board);
   return 0;
}
Registered users can post here. Sign in or register to post.