bborgesr bborgesr - 2 months ago 11
Java Question

Week day Finder in Java

I'm doing a project that consists on: 'Write a program that prompts for a date (month, day, year) and reports the day of the week for that date. It might be
helpful to know that January 1, 1601 was a Monday.'. This is an exercise of 'Building Java Programs - A Back to Basics Approach, 2nd Edition', a book which I bought to teach myself Java. Any feedback is highly appreciated, but I do ask that you explain why you would do something another/a certain way. Thanks!

So, my problem is that while for the dates nearer to 1600's it's giving the correct day (I believe), the same is not true for more recent days, with them having an offset of three days (at least the ones I checked). Why does this happen and how do I fix it? Thanks!

My code:

// finds the day of the week of the given date
public static String dayFinder(int month, int day, int year) {
// handle invalid input
if (month > 12 || month < 1 || day > 31 || day < 1) {
throw new IllegalArgumentException("Month must be between "
+ "1 and 12 and Day must be between 1 and 31.");
}

// convert to "absolute" day, covering day and month
int absoluteDay = monthToDay(month, day, year);

// convert year to days and add to "absolute" day
absoluteDay += yearToDay(year);

if (absoluteDay % 7 == 1) {
return "Monday";
} else if (absoluteDay % 7 == 2) {
return "Tuesday";
} else if (absoluteDay % 7 == 3) {
return "Wednesday";
} else if (absoluteDay % 7 == 4) {
return "Thursday";
} else if (absoluteDay % 7 == 5) {
return "Friday";
} else if (absoluteDay % 7 == 6) {
return "Saturday";
} else { // absoluteDay % 7 == 0
return "Sunday";
}
}

// calculates the number of days present in a given
// date since the beginning of the year
public static int monthToDay(int month, int day, int year) {

// convert to "absolute" day
int absoluteDay = 0, daysTo31 = 0;

// iterate through months
for (int i = 0, loopMonth = month; i < month; i++) {
if (loopMonth == 1 || loopMonth == 3 || loopMonth == 5
|| loopMonth == 7 || loopMonth == 8 || loopMonth == 10
|| loopMonth == 12) {
absoluteDay += 31;
daysTo31 = 0;
} else if (loopMonth == 2) {
if (year % 4 != 0) {
absoluteDay += 28;
daysTo31 = 3;
} else { // leap year
absoluteDay += 29;
daysTo31 = 2;
}
} else { // month = 4, 6, 9 or 10
absoluteDay += 30;
daysTo31 = 1;
}
loopMonth--;
}

// adjust to specific day
absoluteDay -= (31 - day - daysTo31);
return absoluteDay;
}

// calculates the number of days between
// (the beginning of) the given year and
// (the beginning of) the reference year 1601
public static int yearToDay(int year) {

// convert to "absolute" day
int absoluteDay = 0;
year -= 1601;

// iterate through years
for (int i = 0, loopYear = year; i < year; i++) {
if (loopYear % 4 != 0) {
absoluteDay += 365;
} else { // leap year
absoluteDay += 366;
}
loopYear--;
}

return absoluteDay;
}


// Year 1604 (MDCIV) was a leap year starting on Thursday

Answer

Your problem is probably connected with the leap years.

Due to Wikipedia:

Every year that is exactly divisible by four is a leap year, except for years that are exactly divisible by 100; the centurial years that are exactly divisible by 400 are still leap years. For example, the year 1900 is not a leap year; the year 2000 is a leap year. [link]

It's the reason why you have three day too much (1700, 1800, 1900).

Comments