Hi, i'm having a little trouble with my Zeller's Algorithm problem. Everything seems to work fine unless the year is 1600, 1700, 1800, ect. I've been trying to figure out where i went wrong but to no avail. I'd appreciate any advice. Thanks.

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

void DisplayTitle();
void GetDate(int& inputmonth, int& inputday, int& inputyear);
int CalcDayofWeek(int monthnumber, int daynumber, int yearnumber);
void DisplayDay(int G);

int main()
{
	int month, day, year, G;
	DisplayTitle();
	GetDate(month, day, year);
	while (month != 0)
	{
	G = CalcDayofWeek(month, day, year);
	DisplayDay(G);
	GetDate(month, day, year);
	}
	
	return 0;

}

void DisplayTitle()
	{
		cout << "\n\n	Zeller's Algorithm\n";
	}
void GetDate(int& inputmonth, int& inputday, int& inputyear)
	{
		cout << "\n\n   Enter Month (or 0 to exit)     ";
		cin >> inputmonth;
		if (inputmonth != 0)
		{
		cout << "\n\n   Enter day			";
		cin >> inputday;
		cout << "\n\n   Enter year			";
		cin >> inputyear;
		}
		
	}
int CalcDayofWeek(int monthnumber, int daynumber, int yearnumber)
{
	int c, d, G;
	c = yearnumber / 100;
	if (monthnumber < 3)
			{
				monthnumber = monthnumber + 10;
				d = (yearnumber % 100) - 1;	
			}
	else
			{
				monthnumber = monthnumber - 2;
				d = (yearnumber % 100);
			}
			G = (static_cast<int>((2.6 * monthnumber - .2) + daynumber + d + (d/4) + (c/4) - 2 * c) % 7);
			if (G < 0)
				{
					G = G + 7;
				}

	return G;
}

void DisplayDay(int G)
	{
		switch (G)
		{
		case 0: cout << "\n	The Day is Sunday"; break;
		case 1: cout << "\n	The Day is Monday"; break;
		case 2: cout << "\n	The Day is Tuesday"; break;
		case 3: cout << "\n	The Day is Wednesday"; break;
		case 4: cout << "\n	The Day is Thrusday"; break;
		case 5: cout << "\n	The Day is Friday"; break;
		case 6: cout << "\n	The Day is Saturday"; break;
		default: cout << "\n	 Wrong Answer";
		}
	}

Dani AI

Generated

The behaviour for years like 1600/1700/1800/2000 is almost always the same root cause: a mix of truncation vs. mathematical floor and negative remainders. As noted, replacing the algebraic term -2*c with +5*c is safe mod 7, but that alone will not fix the off-by-one produced when January/February force d = (year % 100) - 1 to become negative. Integer division in C++ truncates toward zero (so -1/4 becomes 0) while Zeller expects floor division (so floor(-0.25) is -1). is right to call out the missing floor; 's advice to print intermediate values will quickly reveal where the arithmetic drifts.

A robust fix is to use the integer form of Zeller (no floating rounding, no ambiguous truncation) and then normalize the remainder:

int m = month;
int y = year;
if (m <= 2) { m += 12; --y; }
int K = y % 100;        // year of the century
int J = y / 100;        // zero-based century
int h = (day + (13*(m + 1))/5 + K + K/4 + J/4 + 5*J) % 7; // h: 0=Saturday
h = (h % 7 + 7) % 7;    // normalize to 0..6 in C++
int dow = (h + 1) % 7;  // optional: convert to 0=Sunday,1=Monday,...

For debugging, dump m, y, K, J, the (13*(m+1))/5 term, K/4, J/4, and h before normalization. Test with known anchor dates (for example 2000-01-01 should be Saturday) and ensure the final mapping matches the DisplayDay switch (Zeller uses 0=Saturday). If keeping the floating form, apply floor(...) to each fractional term and normalize the final modulus with (x%7+7)%7 to avoid negative remainders.

Recommended Answers

All 5 Replies

In this wiki article, it notes that to handle the way modulus operator works in software, your last term should be be +5*c rather than -2*c.

Seems to work for me.

Thanks, it gives me an output that's correct unless i use the year 1900,2000, ect.
01
01
2000
should be Sat. but my program still gives me monday.

In my experience, debugging of this sort frequently requires that you do a calculation with pencil and paper specifying the value of each variable associated with a desired input. Then generously sprinkle output statements within the program to show the value of the same variables in your program when you input the same data and compare the two sets of numbers. When/if you find a discrepancy, try to figure out why. The alternative to a bunch of output statements is to learn how to use a debugger to follow the value of one or more variables as the program progesses through the code.

Zeller counted sat=0, sun=1, mon=2 and so on. Your count is different.

From your code it seems you have read the wiki article. The only thing you ommitted was the floor function. In math it is denoted as as vertical line with a little foot at the bottom.

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.