Reputation: 21
I'm trying to write a program that will use Zeller's congruence to find what day of the week a date in histroy was. However, it keeps giving me the same day of the week for entire months, as in the 1st to the 31st will all be on a wednesday for a given month. Can anyone see what I've done wrong?
Any help is much appreciated.
package whatDay;
import java.util.Scanner;
public class DayOfWeek {
public static String year, month, day, date;
public static int yearInt = 0, monthInt = 0, dayInt = 0;
public static boolean leap = false;
private static Scanner sc;
private static Scanner sc2;
private static Scanner sc3;
public static String inputMonth() {
sc = new Scanner(System.in);
System.out.println("Enter the month: ");
month = sc.next();
monthInt = Integer.parseInt(month);
if (monthInt > 12 || monthInt < 1 ) {
System.out.println("Month must be between 1 and 12. Please try again: ");
inputMonth();
}
return month;
}
public static String inputYear() {
sc2 = new Scanner(System.in);
System.out.println("Enter the year: ");
year = sc2.next();
yearInt = Integer.parseInt(year);
if (yearInt < 0 || yearInt > 8000) {
System.out.println("Year must be between 0 and 8000. Please try again: ");
inputYear();
}
if ((yearInt % 4 == 0 && yearInt % 100 != 0) || yearInt % 400 == 0) {
leap = true;
}
return year;
}
public static String inputDay() {
sc3 = new Scanner(System.in);
System.out.println("Enter the day: ");
day = sc3.next();
dayInt = Integer.parseInt(day);
if (monthInt == 1 || monthInt == 3 || monthInt == 5 || monthInt == 7 || monthInt == 8 || monthInt == 10 || monthInt == 12) {
if (dayInt < 1 || dayInt > 31) {
System.out.println("Day must be between 1 and 31: ");
inputDay();
}
}
else if (monthInt == 2 && leap == false) {
if (dayInt < 1 || dayInt > 28) {
System.out.println("Day must be between 1 and 28: ");
inputDay();
}
}
else if (monthInt == 2 && leap == true) {
if (dayInt < 1 || dayInt > 29) {
System.out.println("Day must be between 1 and 29: ");
inputDay();
}
}
else {
if (dayInt < 1 || dayInt > 30) {
System.out.println("Day must be between 1 and 30: ");
inputDay();
}
}
return day;
}
public static String getDate() {
inputYear();
inputMonth();
inputDay();
String[] week = new String[] {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
int h;
int q = monthInt;
int m;
if (monthInt != 1 || monthInt != 2) {
m = monthInt;
}
else {
m = monthInt + 12;
yearInt -= 1;
}
h = (q + Math.floorDiv(13*(m+1), 5) + yearInt + Math.floorDiv(yearInt, 4) - Math.floorDiv(yearInt, 100) + Math.floorDiv(yearInt, 400))%7;
return week[h];
}
public static void main(String[] args) {
System.out.println(getDate());
}
}
Upvotes: 2
Views: 58
Reputation: 914
What you have to change:
Saturday is considered day number 1 in the calculation, therefore you have to change your weekassignment to:
String[] week = new String[] {"Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"};
The correct formula is:
(q + Math.floorDiv(13*(m+1), 5) + yearInt%100 + Math.floorDiv(yearInt%100, 4) - 2*Math.floorDiv(yearInt, 100) + Math.floorDiv(Math.floorDiv(yearInt, 100), 4))%7
q is the day of the month, not the month of the year, you assigned the wrong variable to q, therefore the result was, as you stated, only dependent of your input of the month, the day was not considered.
in the first 2 cases where the year is considered you have to use yearInt%100
, since the year of the century is needed.
the part that gets subtracted has to be multiplied by 2
in the last part you added you need to do 2 floor divisions, because of the potential of rounding down twice instead of only once.
Edit:
One more thing:
if (monthInt != 1 || monthInt != 2)
This will always be true, since all numbers are either not -1 or not -2. Change it to:
if (monthInt != 1 && monthInt != 2)
Upvotes: 1