aussie_aj
aussie_aj

Reputation: 319

Day of the week, java, and Zeller's congruence!

I'm doing this programming exercise out of a textbook where we are given an algorithm for calculating the day of the week called Zeller's congruence. Well do you think I can get the same output as the sample run in the textbook! They go with year 2002, month 3 and day of month 26. The sample reads back Tuesday. I've made several hours of mods and rewrites and can't get anywhere near Tuesday!

It's page 133 of Java Comprehensive textbook 8e if anyone has it... I'm a beginner so constructive feedback most welcome!

Zeller's Congruence

Your advice would be appreciated:

import java.util.Scanner;

public class DayOfTheWeek {

   public static void main(String[] args) {

   // Set up the scanner...
   Scanner input = new Scanner(System.in);

   // Set up the day's of the week with 0 being Sat as per algorithm.           
   final String[] DAY_OF_WEEK = {"Saturday", "Sunday", "Monday", 
       "Tuesday", "Wednesday", "Thursday", "Friday"};

   // Get the year       
   System.out.print("Enter the year (e.g., 2002): ");             
   int year = input.nextInt();

   // Get the month
   System.out.print("Enter the month 1-12: ");  
   int month = input.nextInt();

   // Get the day
   System.out.print("Enter the day 1-31: ");  
   int day = input.nextInt();

   // According to the algorithm Jan is 13 & Feb 14...
   if (month == 1) month = 13;
   else if (month == 2) month = 14;

   // j Is the century.
   int j = year / 100;

   // k Is the year of the century.
   int k = year % 100 ;

   // Calculate
   double h = (month + ((26*(month + 1)) / 10) + k + (k / 4) +
           (j / 4) + (5 * j)) % 7;

   // Cast answer back to integer to get result from array
   int ans = (int)h;

   // Print result
   System.out.println("Day of the week is: " + DAY_OF_WEEK[ans]);

   }
}

Upvotes: 0

Views: 14100

Answers (6)

omkarstha
omkarstha

Reputation: 53

import java.util.Scanner;

public class zelleralgorithm {

    public static void main (String[] args) {

        int month, dayOfMonth, year, cenNumber, yearNumber, weekday, counter = 0;
        String dayname = null;

        Scanner scan = new Scanner(System.in);

        System.out.println("\tZeller's Algorithm");
        System.out.println("**************************************");
        System.out.print("Enter month ( or 0 to exit):\t");
        month = scan.nextInt();


        //handling exception
        while(month > 12){
            System.out.println("Please enter a valid month!\n");
            System.out.print("Enter month ( or 0 to exit):\t");
            month = scan.nextInt();
        }


        while(month != 0) {
            System.out.print("Enter day:\t\t\t");
            dayOfMonth = scan.nextInt();


            //handling exception
            while(dayOfMonth > 32){
                System.out.println("Please enter a valid date!\n");
                System.out.print("Enter day:\t\t\t");
                dayOfMonth = scan.nextInt();
            }


            System.out.print("Enter year:\t\t\t");
            year = scan.nextInt();

            if(month == 1 || month == 2){
                month = 11;
                --year;
            }
            else{
                month = month -2;
            }

            cenNumber = year / 100;
            yearNumber = year % 100;

            weekday = (( (int) (2.6*month-.2) + dayOfMonth + yearNumber + (yearNumber/4) + (cenNumber/4) - (2*cenNumber)) % 7);

            if(weekday < 0){
                weekday = weekday + 7;
            }

            switch(weekday){
            case 0:
                dayname = "Sunday";
                break;
            case 1:
                dayname = "Monday";
                break;
            case 2:
                dayname = "Tuesday";
                break;
            case 3:
                dayname = "Wednesday";
                break;
            case 4:
                dayname = "Thursday";
                break;
            case 5:
                dayname = "Friday";
                break;
            case 6:
                dayname = "Saturday";
                break;
            default:
                dayname = "Exceptional Case error!!";
            }

            System.out.println("\n**************************************");
            System.out.println("\tThe day is "+ dayname);
            System.out.println("**************************************");

            System.out.print("\nEnter month ( or 0 to exit):\t");
            month = scan.nextInt();

            ++counter;
        }
        //while loop end

        //counter
        System.out.println("Number of entries = " + counter);

        scan.close();

    }
}

Upvotes: 0

Neil Armstrong
Neil Armstrong

Reputation: 21

Zeller's Congruence requires INTEGER math in order to function properly. Here is the code in C/C++ (which was tested against the PHP day of week function for EVERY day from year 0 to year 10,000). All variables are of type int:

day_of_week = (((day + (((month + 1) * 26) / 10) + year + (year / 4) + (6 * (year / 100)) + (year / 400)) - 1) % 7);

Notice the "- 1" near the end of the function - this causes it to return a value from 0 thru 6 rather than 1 thru 7 to make the value easier to use, for example, as an index into a string array of day names.

Upvotes: 2

Sam
Sam

Reputation: 11

//just the modified version of the above code.

import java.util.*;

public class Zeller {

final static String[] DAYS_OF_WEEK = {
        "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
        "Friday"
    };

public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    System.out.print("Enter the date in dd/mm/yyyy form: ");

    String[] atoms = input.nextLine().split("/");
    int q = Integer.parseInt(atoms[0]);
    int m = Integer.parseInt(atoms[1]);
    int y = Integer.parseInt(atoms[2]);

    int dd,mm,yy;



    dd = q; mm =m; yy=y;

    if (m < 3) {
        m += 12;
        y -= 1;
    }

    int k = y % 100;
    int j = y / 100;

    int day = ((q + (((m + 1) * 26) / 10) + k + (k / 4) + (j / 4)) +
        (5 * j)) % 7;

    Calendar now = Calendar.getInstance();

    int nd,nm,ny;

    nm =  now.get(Calendar.MONTH) + 1;
    nd = (now.get(Calendar.DATE));
    ny = now.get(Calendar.YEAR);

    if(dd == nd && mm == nm && yy == ny)
        present(day);
    else if(yy<ny)
        past(day);
    else if(yy == ny)
            if(mm == nm)
                if(dd>nd)
                    future(day);
                else
                    past(day);
            else if(mm>nd)
                future(day);
            else 
                past(day);
    else 
        future(day);
}

public static void past(int day)
{
    System.out.println("That date was " + DAYS_OF_WEEK[day] + ".");
}

public static void future(int day)
{
    System.out.println("That date will be " + DAYS_OF_WEEK[day] + ".");
}

public static void present(int day)
{
    System.out.println("Toady is " + DAYS_OF_WEEK[day] + ".");
}
}

Upvotes: 1

twister_void
twister_void

Reputation: 1389

This may work i don't have any idea about that book u may try this code

   import java.util.*;


public class Zeller {
    /**
     *
     * @param args (Not used)
     */
    final static String[] DAYS_OF_WEEK = {
            "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
            "Friday"
        };

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Enter the date in dd/mm/yyyy form: ");

        String[] atoms = input.nextLine().split("/");
        int q = Integer.parseInt(atoms[0]);
        int m = Integer.parseInt(atoms[1]);
        int y = Integer.parseInt(atoms[2]);

        if (m < 3) {
            m += 12;
            y -= 1;
        }

        int k = y % 100;
        int j = y / 100;

        int day = ((q + (((m + 1) * 26) / 10) + k + (k / 4) + (j / 4)) +
            (5 * j)) % 7;

        System.out.println("That date was a " + DAYS_OF_WEEK[day] + ".");
    }
}

Upvotes: 1

amal
amal

Reputation: 1369

 double h = (month + ((26*(month + 1)) / 10) + k + (k / 4) +
       (j / 4) + (5 * j)) % 7;

is WRONG . Note that you dont use days in your current implementation.

Upvotes: 1

Jon Lin
Jon Lin

Reputation: 143926

It looks like this line of code is wrong:

double h = (month + ((26*(month + 1)) / 10) + k + (k / 4) +
(j / 4) + (5 * j)) % 7;

The formula has the day added to the first expression, not the month. So it should look like this:

double h = (day + ((26*(month + 1)) / 10) + k + (k / 4) +
(j / 4) + (5 * j)) % 7;

Upvotes: 3

Related Questions