Moje zadanie to: Zaimplementuj metodę public void ahead (), która przesuwa datę o jeden dzień. W tym ćwiczeniu zakładamy, że każdy miesiąc ma 30 dni. NB! W niektórych sytuacjach musisz zmienić wartości miesiąca i roku.

Ja to zrobiłem:

public class SimpleDate {

    private int day;
    private int month;
    private int year;

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

    @Override
    public String toString() {
        return this.day + "." + this.month + "." + this.year;
    }

    public boolean before(SimpleDate compared) {
        if (this.year < compared.year) {
            return true;
        }

        if (this.year == compared.year && this.month < compared.month) {
            return true;
        }

        if (this.year == compared.year && this.month == compared.month &&
                 this.day < compared.day) {
            return true;
        }

        return false;
    }

    public void advance(){
        if(this.day<30){
            this.day += 1;
        }    
        if(this.day==30 && this.month==12){
            this.day = 1;
            this.month=1;
            this.year +=1;
        }
        if(this.day==30){
            this.day = 1;
            this.month +=1;
        }
    }

    public void advance(int howManyDays){
        if(howManyDays < 30){
            if(this.day<30 && (this.day + howManyDays < 30)){
                this.day += howManyDays;
            }
            if(this.day==30 && this.month==12){
                this.day = howManyDays;
                advance();
            }
            if(this.day==30){
                this.day = howManyDays;
                this.month +=1;
            } 
        }
        if(howManyDays== 30 && this.month==12){
            this.day = howManyDays;
            advance();
        }
        if(howManyDays == 30){
            this.month += 1;
        }
    }
    public SimpleDate afterNumberOfDays(int days){

        SimpleDate obj = new SimpleDate(days, this.month,this.year);
        return obj;

    }

}

Ale kiedy testuję to z:

SimpleDate date = new SimpleDate(30, 12, 2011);  date.advance(3);

Teraz data powinna być 3.1.2012. oczekiwano: [3.1.2012], ale było: [4.12.2011]

-1
i_want_to_code 3 kwiecień 2020, 16:14

3 odpowiedzi

Najlepsza odpowiedź

Polecam po prostu uprościć podejście do tego za pomocą pętli while zamiast wielokrotnych i zagnieżdżonych instrukcji if ...

public void advance(int howManyDays) {
  this.day += howManyDays;

  //Subtracts out the days till within range, incrementing months
  while(this.day > 30) {
    this.day -= 30;
    this.month++;
  }

  //Subtracts out the months till within range, incrementing years
  while(this.month > 12) {
    this.month -= 12;
    this.year++;
  }
}
1
Tim Hunter 3 kwiecień 2020, 13:34

Dzieje się tak, ponieważ ustalasz datę i dzwonisz pod numer advance(). Więc dzień zmienił się na 3, ale teraz dzwonisz advance z datą 3.12.2011, co daje 4.12.2011 tak, jak powinno.

Możesz go rozwiązać na 2 sposoby:

Nieefektywny sposób

Po prostu zadzwoń advance, howManyDays razy:

public void advance(int howManyDays){
    for(int i = 1; i <= howManyDays; i++)
        advance();
}

Skuteczny sposób

To jest ogólny sposób, który będzie działał przez każdą liczbę dni (nawet przez dużą liczbę dni):

public void advance(int howManyDays){
    if(howManyDays + this.day <= 30){
        this.day += howManyDays;
        return;
    }
    int monthsToAdd = (howManyDays + this.day) / 30;
    int yearsToAdd = (monthsToAdd + this.month) / 12;
    int day = (howManyDays + this.day) % 30;
    int month = (monthsToAdd + this.month) % 12;
    if(month == 0) month = 12;
    this.day = day;
    this.month = month;
    this.year += yearsToAdd;
}

public void advance(){
    advance(1);
}
1
Community 20 czerwiec 2020, 09:12

W twoim przypadku testowym przechodzisz w tym bloku:

        if(this.day==30 && this.month==12){
            this.day = howManyDays;
            advance();
        }

Wchodząc do tego bloku, masz day==30, month==12, howManyDays==3.

  • Ustawiłeś dzień na howManyDays, więc now day==3.
  • Wołasz advance(), ponieważ dzień to 3, dzień jest zwiększany, a następnie zwraca się metoda advance().
  • Nie ma innego prawidłowego warunku if, zwraca metoda advance(3).

Zmieniło się tylko pole day.

Zadzwoń pod numer advance() przed ustawieniem dnia i powinno działać.

        if(this.day==30 && this.month==12){
            advance(); // go to the next day, change the month/year if necessary
            this.day = howManyDays-1; // advance() already goes one day forward
        }

Istnieją inne problemy z Twoim kodem, ale pozwolę Ci je znaleźć i naprawić. (np. co, jeśli day to 27, a howManyDays to 3?)

Zdecydowanie sugeruję, abyś nauczył się używać debugera krok po kroku do rozwiązywania tych łatwych problemów logicznych. To cenna i bardzo przydatna umiejętność.

1
jhamon 3 kwiecień 2020, 13:36