0

I have a problem with a task, I need to add a method to a class that returns the name of the day of the week for a given date. You have to do it in two ways, using the methods of shifting by a week (comparing to the selected reference date, e.g. May 14, 2023 is Sunday) and by determining using the modulo operation (https://en.wikipedia.org/w/index.php?title=Zeller%27s_congruence&oldid=1033222037.

my code shows wrong results using both methods, i don't understand why. e.g. when given 3/17/2030, the reference method displays Wednesday, and the Zeller algorithm displays Friday, when the correct result is Sunday. please help me find the error. I don't want to use any built-in classes or functions

import java.util.Scanner;
import java.util.Comparator;
   class DateComparator implements Comparator<Date>{

    @Override
    public int compare(Date date1, Date date2){
        int yearComparison = Integer.compare(date1.getYear(), date2.getYear());
        if( yearComparison != 0){
            return yearComparison;
        }

        int monthComparison = Integer.compare(date1.getMonth(), date2.getMonth());
        if(monthComparison != 0){
            
            return monthComparison;
        }



        return Integer.compare(date1.getDay(), date2.getDay());
    }
}

class Month{
    private int monthNumber;
    private String name;
    private int days;

    public Month(int monthNumber, String name, int days){
        this.monthNumber = monthNumber;
        this.name = name;
        this.days = days;
    }
    public int getMonthNumber() {
        return monthNumber;
    }

    public int getDays() {
        return days;
    }

    public void setDays(int days){
        this.days = days;
    }
}

public class Date {

    Months monthsObj = new Months();
    private int year;
    private int month;
    private int day;

    public Date() {
    }

    public Date(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public int getYear(){
        return year;
    }

    public void setYear(int year){
        this.year = year;
    }

    public int getMonth(){
        return month;
    }

    public void setMonth(int month){
        this.month = month;
    }

    public int getDay(){
        return day;
    }

    public void setDay(int day){
        this.day = day;
    }

    public void printDate(){
        System.out.println(year + "-" + month + "-" + day);
    }


    public void incrementWeek(){
        int daysInMonth = monthsObj.getDaysInMonth(year, month);
        day += 7;
        if(day > daysInMonth){
            day -= daysInMonth;
            month++;
            if(month > 12){
                year++;
                month = 1;
            }
        }
    }

   

    public void decrementWeek(){
        int daysInPreviousMonth;
        int daysToRemove = 8 - day;
        if(daysToRemove <= 0){
            day -= 7;
        }else{
            month--;
            if(month == 0){
                month = 12;
                year--;
            }
            daysInPreviousMonth = monthsObj.getDaysInMonth(year, month);
            day = daysInPreviousMonth + 1 - daysToRemove;
        }
    }


    public void whatDay() {
        int h = (day + 13 * (month + 1) / 5 + year % 100 + (year % 100) / 4 + (year / 100) / 4 - 2 * (year / 100)) % 7;

        String[] days = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
        System.out.println(days[h]);
    }

    public void moveWeek(Date reference, Date calendar, int result){

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

        if(result > 0){
            while((reference.getYear() != calendar.getYear()) || (reference.getMonth() != calendar.getMonth()) || (reference.getDay()-calendar.getDay() >= 7)){
                calendar.incrementWeek();
                calendar.printDate();
            }
        }

        if(result < 0){
            while((reference.getYear() != calendar.getYear()) || (reference.getMonth() != calendar.getMonth()) || ((reference.getDay()-calendar.getDay() >= 7)||(reference.getDay()- calendar.getDay()<0))){
                calendar.decrementWeek();
                calendar.printDate();

            }
        }


        int difference = reference.getDay() - calendar.getDay();
        System.out.println(days[6-difference]);

    }



    public static void main(String[] args) {
        DateComparator comparator = new DateComparator();
        Scanner sc = new Scanner(System.in);
        System.out.println("podaj dzien, miesiac i rok:");
        int day = sc.nextInt();
        int month = sc.nextInt();
        int year = sc.nextInt();

        Date reference = new Date(2023, 5, 14);
        Date calendar = new Date(year, month, day);
        calendar.moveWeek(reference, calendar, comparator.compare(reference, calendar));
        calendar.whatDay();
      

    }
}

class Months{
    private static final Month[] months = {
            new Month(1, "January", 31),
            new Month(2, "February", 28),
            new Month(3, "March", 31),
            new Month(4, "April", 30),
            new Month(5, "May", 31),
            new Month(6, "June", 30),
            new Month(7, "July", 31),
            new Month(8, "August", 31),
            new Month(9, "September", 30),
            new Month(10, "October", 31),
            new Month(11, "November", 30),
            new Month(12, "December", 31)
    };

    public boolean isLeapYear(int year){

        return (year % 4 == 0 && year % 100 !=0) || year % 400 == 0;
    }

    public int getDaysInMonth(int year, int month){

        if(isLeapYear(year) && month == 2){
            months[1].setDays(29);
        }

        return months[month-1].getDays();
    }

}
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Ala
  • 3
  • 2
  • Please give a couple of examples of input, expected result and observed result. – Ole V.V. May 31 '23 at 06:22
  • When posting a schoolwork question, make an explicit not of that fact. Your phrase "You have to it in two ways" is unclear, but presumably means you have been given a homework assignment, and by "You have to do" you really mean "I have to do". – Basil Bourque May 31 '23 at 18:18

2 Answers2

1

The Wikipedia documentation for Zeller's congruence states that h will be an index starting with "Saturday".

h is the day of the week (0 = Saturday, 1 = Sunday, 2 = Monday, ..., 6 = Friday)

Your days array in the whatDay method is starting with "Monday".

{ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
{ "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" };
Reilas
  • 3,297
  • 2
  • 4
  • 17
  • I changed it and now whatDay() function gives proper results but I still don't know what to do with moveWeek(), thanks anyways – Ala May 31 '23 at 15:53
  • However, no. for 17.2.2034 it gives Tuesday while it's Friday :/ – Ala May 31 '23 at 16:00
  • Have you double-checked the evaluation of _h_? Maybe there is a truncation within. Additionally, I noticed the solution uses a _floor_. – Reilas May 31 '23 at 16:14
0

The answer is more simple than you believe. Test the snippet code below. I think it will solve your problem.



    private final String showWeekDayName(String stringDate) throws ParseException {
        final Date date = new SimpleDateFormat("dd/MM/yyyy").parse(stringDate);
        
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG_FORMAT, Locale.getDefault());
    }

Just make sure to update your date format and the locale you need the week name.

thiagotrss
  • 129
  • 4
  • 2
    Three problems: (i) `Date`, `Calendar`, `SimpleDateFormat` were outdated in java 8 (almost 10 years ago); better use the `java.time` package; (ii) from the question: "*You have to do it in two ways, using the methods of shifting by a week (...) and by determining using the modulo operation*"; (iii) input is not a `String` – user16320675 May 30 '23 at 21:42
  • @user16320675, I am still misunderstanding this misconception on this website, in terms of _Calendar_. How does the use of those three classes defy the requirement of the task? They are all valid classes, still in use by Java, as of version 20. – Reilas May 30 '23 at 23:28
  • 1
    @Reilas There is a long list of problems with the legacy date-time classes, addressed many times. Written by people who did not understand date-time handling. Not object-oriented. Awkwardly developed first in `Date`, then later bolting on `Calendar` which only made things worse. Came from legacy code inherited before Java was invented. Terrible design decisions such as subclasses whose inheritance the documentation tells us we should ignore and pretend does not exist. Lacks key concepts such as date-time without zone/offset. Missing SQL types. And more. JSR 310 did not come out of nowhere. – Basil Bourque May 31 '23 at 06:01
  • 1
    I think you answered the question in the title, not the question as spelled out in the body. And only the OP can tell (or their teacher or manager), but it sounds to me like this should be done without using the library date classes (@user16320675 is correct, for production code one would use `LocalDate` and `DayOfWeek` from java.time). – Ole V.V. May 31 '23 at 06:15
  • @Reilas I am still trying to understand your problem with the general `java.util.Calendar` bashing on Stack Overflow and in the Java community as a whole. Until now without much success, sorry. The general consensus is that we have given up completely on the old date-time classes several years ago. You’re perfectly entitled to your own opinion, as we are to ours. You are perfectly correct, most date and time tasks can be solved using the old classes. They are valid. You can use `Calendar` all that you want (only not in code that I need to maintain). I will find some links that may provide more – Ole V.V. May 31 '23 at 08:25
  • @Reilas If you’re curious, you can read more in [this Oracle document](https://www.oracle.com/technical-resources/articles/java/jf14-date-time.html) and also [here](https://programminghints.com/2017/05/still-using-java-util-date-dont/), [here](https://stackoverflow.com/questions/1571265/why-is-the-java-date-api-java-util-date-calendar-such-a-mess), [here](https://stackoverflow.com/questions/1969442/whats-wrong-with-java-date-time-api), [the EDIT at the bottom of this answer](https://stackoverflow.com/a/344400/5772882) and [here](https://stackoverflow.com/questions/69730254/how-to-correctly-). – Ole V.V. May 31 '23 at 14:41
  • @BasilBourque, you imply there is some other type of design implementation here. There is not, it's a method which evaluates the weekday of a given date. How is this overlooked? – Reilas May 31 '23 at 15:56
  • 1
    @OleV.V., I'm misunderstanding where the design is, and where any of those factors play a role. Additionally, you're under the impression that since there is a newer date and time framework, it some how invalidates the current framework. If that were the case, the framework would be removed. We are not talking about a design here, just a method. I'm amazed at how deviated a group of people can be. Where's the Kool-aid? – Reilas May 31 '23 at 16:02
  • 1
    No, @Reilas, newer is not necessarily better. Only in this example it happens to be a lot better. And no, Oracle has only recently started removing stuff from the standard library, so presence is different from endorsement. [The official Oracle tutorial](https://docs.oracle.com/javase/tutorial/datetime/iso/legacy.html) refers to `Calendar` and the other date and time classes from Java 1.0 and 1.1 as (quote) *legacy*. Why that is not mentioned in the API documentation is, admitted, a bit of a mystery to me. And I am not deviated if I understand that word (not a native English speaker). – Ole V.V. May 31 '23 at 16:30
  • 1
    @Reilas "If that were the case, the framework would be removed." That is not true at all. You must be unfamiliar with the long history of Java. Java has accumulated *many* pieces of cruft over the decades that would be omitted if Java were re-created today. For example, all the old I/O classes remain in place despite the arrival of NIO and NIO.2. The Java team has always been committed to upward compatibility as one of their highest priorities. That means leaving the old cruft in place is the default option, with rare exceptions. Why the cruft is so rarely marked as deprecated is a mystery. – Basil Bourque May 31 '23 at 18:19
  • 2
    `java.time.LocalDate.of ( 2023 , Month.MAY , 14 ).getDayOfWeek ( ).getDisplayName ( TextStyle.FULL_STANDALONE , Locale.CANADA_FRENCH )` ⇒ dimanche – Basil Bourque May 31 '23 at 18:28
  • 1
    @Reilas I'm afraid the misconception is yours. [That reference](https://docs.oracle.com/javase/tutorial/datetime/iso/legacy.html) clearly refers to the `Calendar`, `Date`, `TimeZone`, and `GregorianCalendar` classes as being “legacy”, explains their drawbacks, and refers to their use in the past tense, prior to Java 8. If you need more of an explanation of the term “legacy”, see Wikipedia, [*Legacy system*](https://en.wikipedia.org/wiki/Legacy_system). – Basil Bourque May 31 '23 at 18:33
  • @BasilBourque, if the coding language you're using has, in your opinion, built up _"... cruft over the decades..."_ then you shouldn't be using it. Choose a coding language that makes sense to you. The fact that you can't understand that this question does not imply any sort of design, and is simply stating, _"I need to add a method to a class that returns the name of the day of the week for a given date"_, is strange to me. You should educate yourself on the term _"context"_; otherwise you'll create, what is referred to as, _"non-sense"_. – Reilas May 31 '23 at 18:35
  • @BasilBourque, this question is not talking about a design, it's a question about a method in a class. You truly cannot understand the difference? – Reilas May 31 '23 at 18:38
  • @OleV.V., how reflective. I'm not surprised either. – Reilas May 31 '23 at 18:40