Home > Net >  Having trouble developing incrementMinutesBy method
Having trouble developing incrementMinutesBy method

Time:10-14

I am trying to create a digital clock an am currently trying to fix my incrementMinutesBy method. 

I need this method to increase both the minutes and if necessary the hours. I need the final this.minutes to be the sum of the previous this.minutes and the parameter, modulo the number of minutes in an hour.

I also need the final this.hours to be the sum of the previous this.minutes and the parameter, divided by the number of minutes in an hour. My method so far begins on line 94.

public class DigitalClock
{
    private int currentHour;
    private int currentMinutes;

    public int getHour()
    {
        return currentHour;
    }

    public void setHour(int currentHour)
    {
        this.currentHour = currentHour;
    }

    public int getMinutes()
    {
        return currentMinutes;
    }

    public void setMinutes(int currentMinutes)
    {
        this.currentMinutes = currentMinutes;
    }

    public static final int HOUR_MAX = 23; // Refactored hourly max
    public static final int HOUR_MIN = 0; // Refactored hourly min
    public static final int MINUTES_MAX = 59; // Refactored minute max
    public static final int MINUTES_MIN = 0; // Refactored minute min
    public static final int TOTAL_NUMBERS_HOURS = 24;
    public static final int TOTAL_NUMBERS_MINUTES = 60;

    /**
     * Creates a new digital clock with the time set at the given
     * hours and minutes.
     * 
     * @precondition 0 <= hour <= 23 AND 0 <= minutes <= 59
     * @postcondition getHour()==hour AND getMinutes()==minutes
     * 
     * @param hour the hour to set for the time
     * @param minutes the minutes to set for the time
     */
    public DigitalClock (int hour, int minutes) // 2-parameter constructor (parameters: int hour and int minutes)
    {
        // enforcing hourly preconditions using appropriate ranges
        if (hour >= HOUR_MIN && hour <= HOUR_MAX){
            currentHour = hour;
        }
        else {
            currentHour = 0;
            //throw an exception on invalid hour's input
            throw new IllegalArgumentException("Invalid input for Hours");
        }
        // enforcing minute preconditions using appropriate ranges
        if (minutes >= MINUTES_MIN && minutes <= MINUTES_MAX) {
            currentMinutes = minutes;
        }
        else {
            currentMinutes = 0;
            //throw an exception on invalid minute's input
            throw new IllegalArgumentException("Invalid input for Minutes");
        }
    }

    /**
     * Advances the entire clock by the given number of hours.
     * If the hours advances past 23 they wrap around.
     * 
     * @precondition hours >= 0
     * @postcondition  the clock has moved forward
     *  by the appropriate number of hours
     * 
     * @param hours the number of hours to add
     */
    public void incrementHoursBy(int hour)
    {
        int h = getHour() hour; {
        // if statement enforcing precondition
        if(h>HOUR_MAX)
            h%=TOTAL_NUMBERS_HOURS;
        // increasing this.hours by the parameter 
        setHour(h);}
        // if statement which prevents negative hours from being inputted
        if (h<HOUR_MIN) {
            throw new IllegalArgumentException("Invalid input. No negative hours");
        }
    }
    
    public void incrementMinutesBy(int minutes) {
        int m = getMinutes() minutes;
        m  ;
        if (m > MINUTES_MAX) {
            m%=TOTAL_NUMBERS_MINUTES;
            setMinutes(m);
        }
        if (m<MINUTES_MIN) {
            throw new IllegalArgumentException("Invalid input. No negative minutes");
        }
        else
        {
            System.out.println("Minutes are: " m);
        }
    }

    public static void main(String args[])
    {
        DigitalClock obj=new DigitalClock(12, 15);
        obj.incrementHoursBy(HOUR_MAX);
        obj.incrementMinutesBy(MINUTES_MAX);
        DigitalClockFormatter();
    }

    public static void DigitalClockFormatter() {
        // method for class DigitalClockFormatter

    }
}

CodePudding user response:

To simplify the implementation, it's beter to save totalMinutes internaly, but not the separate hours and minutes.

public final class DigitalClock {

    private static final int MINUTES_PER_HOUR = (int)TimeUnit.HOURS.toMinutes(1);
    private static final int MINUTES_PER_DAY = (int)TimeUnit.DAYS.toMinutes(1);

    private int totalMinutes;

    public DigitalClock(int hour, int minutes) {
        setHour(hour);
        setMinutes(minutes);
    }

    public int getHour() {
        return totalMinutes / MINUTES_PER_HOUR;
    }

    public int getMinutes() {
        return totalMinutes % MINUTES_PER_HOUR;
    }

    public void setHour(int hour) {
        if (hour < 0 || hour > 23)
            throw new IllegalArgumentException("'hour' should be within [0;23]");

        totalMinutes = (int)TimeUnit.HOURS.toMinutes(hour)   getMinutes();
    }

    public void setMinutes(int minutes) {
        if (minutes < 0 || minutes > 59)
            throw new IllegalArgumentException("'minutes' should be within [0;59]");

        totalMinutes = (int)TimeUnit.HOURS.toMinutes(getHour())   minutes;
    }

    public void incrementHoursBy(int hour) {
        totalMinutes = withinDay((int)TimeUnit.HOURS.toMinutes(hour)   totalMinutes);
    }

    public void incrementMinutesBy(int minutes) {
        totalMinutes = withinDay(totalMinutes   minutes);
    }

    private static int withinDay(int totalMinutes) {
        totalMinutes %= MINUTES_PER_DAY;

        if (totalMinutes < 0)
            totalMinutes = MINUTES_PER_DAY   totalMinutes;

        return totalMinutes;
    }

    @Override
    public String toString() {
        return String.format("d:d", getHour(), getMinutes());
    }

}

CodePudding user response:

I believe that your calculations can also be achieved by subtraction. Consider the following example.

If currentHour is 23 and you add two hours, then the result should be 1 (one).

23   2 = 25
25 % 24 = 1
25 - 24 = 1

Similarly for currentMinutes. However, for currentMinutes you also need to increment currentHour if the result of the increment (to currentMinutes) is greater than MINUTES_MAX. And when you increment currentHour you also need to check whether the incremented currentHour value is greater than HOUR_MAX. In other words, if currentHour is 23 and currentMinutes is 55 and you incrementMinutesBy(10), then:

55   10 = 65
65 - 60 = 5

Therefore currentMinutes is set to 5 and currentHour needs to be incremented. Therefore:

23   1 = 24
24 - 24 = 0

So currentHour needs to be set to 0 (zero).

Also, as explained in the book Java by Comparison, methods need to fail fast so the first thing you should do in both method incrementHoursBy and method incrementMInutesBy is to check the value of the method argument – and not the result of the calculation. After all, you wrote in the code comments that the pre-condition is that the method argument not be negative – even though I think it would be logical to be able to set the digital clock backwards. I mean that's what you do when daylight saving ends and the clocks get turned back one hour. But then again, with your [digital] clock, you could achieve the same result by invoking incrementHoursBy(HOUR_MAX)

Consider the following code:

public class DigitalClock {
    private int currentHour;
    private int currentMinutes;

    public int getHour() {
        return currentHour;
    }

    public void setHour(int currentHour) {
        this.currentHour = currentHour;
    }

    public int getMinutes() {
        return currentMinutes;
    }

    public void setMinutes(int currentMinutes) {
        this.currentMinutes = currentMinutes;
    }

    public static final int HOUR_MAX = 23; // Refactored hourly max
    public static final int HOUR_MIN = 0; // Refactored hourly min
    public static final int MINUTES_MAX = 59; // Refactored minute max
    public static final int MINUTES_MIN = 0; // Refactored minute min
    public static final int TOTAL_NUMBERS_HOURS = 24;
    public static final int TOTAL_NUMBERS_MINUTES = 60;

    /**
     * Creates a new digital clock with the time set at the given hours and minutes.
     * 
     * @precondition 0 <= hour <= 23 AND 0 <= minutes <= 59
     * @postcondition getHour()==hour AND getMinutes()==minutes
     * 
     * @param hour    the hour to set for the time
     * @param minutes the minutes to set for the time
     */
    public DigitalClock(int hour, int minutes) {
        // enforcing hourly preconditions using appropriate ranges
        if (hour >= HOUR_MIN && hour <= HOUR_MAX) {
            currentHour = hour;
        }
        else {
            currentHour = 0;
            // throw an exception on invalid hour's input
            throw new IllegalArgumentException("Invalid input for Hours");
        }
        // enforcing minute preconditions using appropriate ranges
        if (minutes >= MINUTES_MIN && minutes <= MINUTES_MAX) {
            currentMinutes = minutes;
        }
        else {
            currentMinutes = 0;
            // throw an exception on invalid minute's input
            throw new IllegalArgumentException("Invalid input for Minutes");
        }
    }

    /**
     * Advances the entire clock by the given number of hours. If the hours advances
     * past 23 they wrap around.
     * 
     * @precondition hours >= 0
     * @postcondition the clock has moved forward by the appropriate number of hours
     * 
     * @param hours the number of hours to add
     */
    public void incrementHoursBy(int hour) {
        // if statement which prevents negative hours from being inputted
        if (hour < HOUR_MIN  ||  hour > HOUR_MAX) {
            throw new IllegalArgumentException("Invalid input. Between 0 & 23");
        }
        int h = currentHour   hour;
        // if statement enforcing precondition
        if (h > HOUR_MAX) {
            h -= TOTAL_NUMBERS_HOURS;
        }
        // increasing this.hours by the parameter
        setHour(h);
    }

    public void incrementMinutesBy(int minutes) {
        if (minutes < MINUTES_MIN  ||  minutes > MINUTES_MAX) {
            throw new IllegalArgumentException("Invalid input. Between 0 & 59");
        }
        int m = getMinutes()   minutes;
        if (m > MINUTES_MAX) {
            incrementHoursBy(1);
            m -= TOTAL_NUMBERS_MINUTES;
            setMinutes(m);
        }
    }

    public static void main(String args[]) {
        DigitalClock obj = new DigitalClock(22, 55);
        obj.incrementHoursBy(1);
        obj.incrementMinutesBy(10);
        DigitalClockFormatter(obj);
    }

    public static void DigitalClockFormatter(DigitalClock dc) {
        System.out.printf("d:d", dc.getHour(), dc.getMinutes());
    }
}

Running above code displays:

00:05

Alternatively, you could use the date-time API.

import java.time.LocalTime;

public class DigiClok {
    private LocalTime clock;

    public DigiClok(int hour, int minute) {
        clock = LocalTime.of(hour, minute); // throws java.time.DateTimeException if invalid arguments
    }

    public int getHour() {
        return clock.getHour();
    }

    public void setHour(int currentHour) {
        // class 'java.time.LocalTime' is immutable.
        int minute = clock.getMinute();
        clock = LocalTime.of(currentHour, minute);
    }

    public int getMinutes() {
        return clock.getMinute();
    }

    public void setMinutes(int currentMinutes) {
        int hour = clock.getHour();
        clock = LocalTime.of(hour, currentMinutes);
    }

    public boolean equals(Object obj) {
        boolean equal = this == obj;
        if (!equal) {
            if (obj instanceof DigiClok) {
                DigiClok other = (DigiClok) obj;
                equal = clock.equals(other.clock);
            }
        }
        return equal;
    }

    public int hashCode() {
        return clock.hashCode();
    }

    public String toString() {
        return clock.toString();
    }

    public void incrementHoursBy(int hour) {
        clock = clock.plusHours(hour); // also handles negative 'hour'
    }

    public void incrementMinutesBy(int minutes) {
        clock = clock.plusMinutes(minutes); // also handles negative 'minute'
    }

    public static void main(String[] args) {
        DigiClok obj = new DigiClok(22, 55);
        obj.incrementHoursBy(1);
        obj.incrementMinutesBy(10);
        System.out.println(obj);
    }
}
  •  Tags:  
  • java
  • Related