Need Help Computing Day Of Week

Hello, I'm having trouble seeing where my code is going wrong. I'm new to C++ so I might be missing something really obvious, but I doubt it since I've asked my professor for help and he couldn't see what was wrong with the code.

Basically, my assignment is to calculate the day of the week given an input date. The problem itself is here: https://pastebin.com/esLWtSWX

My code compiles and runs fine, but it always outputs the wrong day of the week, and it's not always off by a specific amount either.

For example: given the input "2 21 2019" (a Friday) it outputs Thursday, so it's off by one day. However, given the input "3 12 2019" (a Tuesday) it outputs Saturday, a whole 3 (or 4) days off.

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
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <cmath>
using namespace std;

const double JDN_CONST = 1720994.5;
const double YEAR_CONST = 365.25;
const double MONTH_CONST = 30.6001;

long Res1(int day, int month, int year)	//function to find intRes1 using formula intRes1 = ((2 - year) / (100 + year)) / 400
{
	bool isGregorian = ( (year > 1582) || ((year == 1582) && (month >= 10) && (day > 15)) );	//determines the truth value of if the date is using the Gregorian calendar
	double a = 2 - year;
	double b = 100 + year;
	double c = (a / b) / 400;
	
	cout << "intRes1 : " << floor(c) << endl;
	
	if(isGregorian) {return floor(c);}
	else return 0;
}

long Res2(int year)	//function to find intRes2 using formula 365.25 * year
{
	cout << "intRes2 : " << YEAR_CONST * year << endl;
	
	return static_cast<int>(YEAR_CONST * year);
}

long Res3(int month)	//function to find intRes3 using formula 30.6001 * (month + 1)
{
	cout << "intRes3 : " << static_cast<int>(MONTH_CONST * (month + 1)) << endl;
	
	return static_cast<int>(MONTH_CONST * (month + 1));
}

long JulianDayNumber(int day, int month, int year)	//function to find the JDN using formula JDN = intRes1 + intRes2 + intRes3 + day + 1720994.5
{
	cout << "JDN : " << Res1(day, month, year) + Res2(year) + Res3(month) + day + JDN_CONST << endl;
	
	return static_cast<int>(Res1(day, month, year) + Res2(year) + Res3(month) + day + JDN_CONST);
}

string DayOfWeek(int day, int month, int year)	//function to find the day of the week of a given date using formula (JDN + 1) % 7. this outputs an int (0 <= i <= 6) where 0 corresponds to Sunday, 1 to Monday, etc.
{
	long JDN = JulianDayNumber(day, month, year);
	int dayInt = ((JDN + 1) % 7);
	
	cout << "dayInt : " << dayInt << endl;
	
	if(dayInt == 0) return "Sunday";
	else if(dayInt == 1) return "Monday";
	else if(dayInt == 2) return "Tuesday";
	else if(dayInt == 3) return "Wednesday";
	else if(dayInt == 4) return "Thursday";
	else if(dayInt == 5) return "Friday";
	else if(dayInt == 6) return "Saturday";
}

int main()
{
	int day;
	int month;
	int year;
	ifstream inData;
	
	inData.open("indata7.txt");
	if(inData.is_open())	//if the file indata7.txt is found, reads from file. if not, takes user input
	{
		while(!inData.eof())
		{
			inData >> month >> day >> year;
			cout << "Date: " << month << "/" << day << "/" << year << ", Day of week: " << DayOfWeek(day, month, year) << endl;
		}
	}else	//user input
	{
		cout << "input date in order month day year		(example input: '2 21 2019')" << endl << "input 'stop' to end input" << endl;
		cout << " " << endl;
		while(month > 0)
		{
			cin >> month >> day >> year;
			cout << "Date: " << month << "/" << day << "/" << year << ", Day of week: " << DayOfWeek(day, month, year) << endl;
			cout << " " << endl;
		}
	}
	
	return 0;
}

edit 1: changed JulianDayNumber() to type long

Any insight into this problem is much appreciated!


Last edited on
Have you run the program with your debugger, single stepping through the day of week function and verifying that the numbers produced are what you expect? You may also want to step into each function to verify all the calculations.

By the way why is JulianDayNumber() returning a double? After all you casted the return value to an int in your return call.
When I calculate each value I output it. I've verified these numbers to be correct with a calculator. Originally I made JulianDayNumber() a double because it calculates the JDN with JDN_CONST = 1720994.5, though I see why it's redundant for it to be a double. I'll change it, but I still get the same output.
Last edited on
The general c++ area is for more advanced topics :). next time perhaps try the beginners section? You are new, as you said
I think you need to start over on your calculations.

First of all, a year is not 365.25 days long. Every 100 years, you skip the leap year, unless the year is divisible by 400, in which case the leap year is left in. so, the length of the year is not exactly 365.25 days. I think you are accounting for the 4/100/400 stuff in your Res1, but you can't use 365.25 in YEAR_CONST.

On top of that, it doesn't really matter. If year X ends on Friday, year X+1 starts on Saturday, regardless of whether year X has 365 of 366 days. The average year length is useful for figuring out roughly how many days are in a large span of years, but not for fine calculations of exact day-of-the-week.

I think you are trying to account for all this with Res1 and Res2, but you are missing your mark.

Similarly, look at MONTH_CONST. I have no idea where you got that number from (it's close to 365/12, but not quite). But using that number, you would calculate that the nth day of month X is exactly 30.6001 days before the nth day of month X+1. Even if you could properly account for fractional days, months are not the same length. Some have 30 days, and some have 31 days. February has 28 or 29 depending on the year. So. a simple multiplication/addition formula like you have ain't gonna cut it.
@Rascake: I didn't see that section at first, thanks for pointing it out. Should I move this topic there?

@doug4: Those are just the values I was given in the assignment. I'm not sure how I would change them to make the code work while still using the functions I was given. I'll ask my professor about using a different method.
Last edited on
Did you chekc the formula in the link you mention as "problem source" https://pastebin.com/esLWtSWX ?
If I use it manualy to get the JDN for 1 1 1900 (which I know by hart it's a Monday) it differs from the result here: http://numerical.recipes/julian.html
So there is chance your program is correct, alas not the formula you use.
Registered users can post here. Sign in or register to post.