bborgesr - 10 months ago 42

Java Question

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).

Source (Stackoverflow)