I'm new to C/C++ and I'm having difficulty with calculating leap years in my Zeller's Algorithm program (based off of the Gregorian Calendar). I've lost sleep over this code for the last week and this is my final breaking point.
I continually get "This day is Friday." for input 1 16 2012 ... which should be Monday instead.. etc, etc.

If anyone could help or give me hints, that would be excellent.
Here is my code so far:

``````#include<iostream>
using namespace std;

void DisplayTitle();
// displays the title
void GetDate(int&, int&, int&);
// collects the user's input and/or terminates the program
int CalcDayOfWeek();
// returns the value for G --> calculates the day of the week
void DisplayDay(int);
// displays what day G represents

int month, dayOfMonth, year;

int main()
{
//int M, K, C, D; ---- don't need these
int G;

while(1)
{
DisplayTitle();
GetDate(month, dayOfMonth, year);
G = CalcDayOfWeek() % 7;
DisplayDay(G);
}

system("pause");
return 0;
}

// DisplayTitle Function --- test: WORKS
void DisplayTitle()
{
cout << "\n          Zeller's Algorithm" <<endl;
}

// GetDate Call-by-reference Function --- tested: WORKS
void GetDate(int& month, int& dayOfMonth, int& year)
{
cout << "\n     Enter month (or 0 to exit)   ";
cin >> month;
if (month==0)
exit(1);
cout << "\n     Enter day                    ";
cin >> dayOfMonth;
cout << "\n     Enter year                   ";
cin >> year;
}

//CalcDayOfWeek Function --- test:
int CalcDayOfWeek()
{
double G;
int K = dayOfMonth;
int C = year / 100;
int D = year % 100;
int M = month - 2;

// January of a leap year --- that is NOT a century mark such as 1600, 1800, 2000; --- test:
if((year % 400 == 0)&&(month < 2)&&(D != 0))
{
M = month + 10;
D -= 1;
G = (static_cast<int>(2.6 * M - 0.2) + K + D + (D/4.0) + (C/4.0) + 2 * C);
}

// February of a leap year (before the 29th) --- that is NOT a century mark --- test:
if ((year % 400 == 0)&&(month == 2)&&(K < 29)&&(D !=0))
{
M = month + 10;
D -= 1;
G = static_cast<int>((2.6 * M - 0.2) + K + D + (D/4.0) + (C/4.0) + 2 * C) ;
//G -= 4; testing this out..
}

if(month <= 2)
{
M = month + 10;
D -= 1;
}

G = static_cast<int>((2.6 * M - 0.2) + K + D + (D/4.0) + (C/4.0) + 2 * C);

if(G < 0)
G +=7;

if(G > 6)
G -= 7;

cout << "M = " << M <<endl;
cout << "K = " << K <<endl;
cout << "C = " << C <<endl;
cout << "D = " << D <<endl;
cout << "G = " << G <<endl <<endl;

return(static_cast<int>(G));
}

// DisplayDay Function --- test:
void DisplayDay(int day)
{
cout << endl <<endl << "          This day is ";

switch(day)
{
case '0':
cout << "Sunday.";
break;
case 1:
cout << "Monday.";
break;
case 2:
cout << "Tuesday.";
break;
case 3:
cout << "Wednesday.";
break;
case 4:
cout << "Thursday.";
break;
case 5:
cout << "Friday.";
break;
case 6:
cout << "Saturday.";
break;
}
cout <<endl <<endl;
}``````

The first observation is that you are using floating-point arithmetic (e.g. 2.6 * M - 0.2). The Zeller algorithm is based on the fact that integer arithmetic is used. In other words, (D / 4.0) is not equal to (D / 4), the former is in floating point arithmetic and the latter is in integer arithmetic, and they will yield different results, even when the floating-point value is rounded or cast to int.

According to this wiki article, the Zeller's algorithm already takes the leap years into account. You don't need all these if-statements. Why don't you implement the formula as is?

To convert the input such that it fits in the formula, all you have to do is check if the month is 1 or 2, in which case, you should make the month 13 or 14, respectively, and then decrease the year by one. Then, the formula should work:

``````int CalcDayOfWeek()
{
if(month < 3) {
month += 12;
year--;
};
int K = year % 100;
int J = year / 100;

return (dayOfMonth + ((month + 1) * 26) / 10 + K + K / 4 + J / 4 + 5 * J) % 7;
};``````

Finally, according to the wiki, the day of the week is such that 0 = saturday, not sunday.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.