Search code examples
javadatejava-8java-timelocaltime

Lock underflow/overflow with Java LocalTime


When subtracting a given amount from a LocalTime object, I've realised that overflow/underflow can occur.

Example:

00:30 - 35 minutes = 23:55
23:30 + 35 minutes = 00:05

For my application, I would like lock times such that the above would generate 00:00 on underflow, and 23:59 on overflow.

Is this possible?


Solution

  • My suggestion is:

        LocalTime orig = LocalTime.of(0, 30);
        int minutesToSubtract = 35;
        long minutesSinceMidnight = ChronoUnit.MINUTES.between(LocalTime.MIN, orig);
        LocalTime result;
        if (minutesToSubtract > minutesSinceMidnight) {
            // Subtracting the minutes will pass midnight at start of day
            result = LocalTime.MIN;
        } else {
            // Normal case, no underflow
            result = orig.minusMinutes(minutesToSubtract);
        }
        System.out.println(result);
    

    The above assumes that minutesToSubtract is non-negative. If negative numbers may occur, you need to check for both underflow and overflow.

    The case of checking for overflow (more than 23:59:59.999999999) is similar. Use LocalTime.MAX for end of day.

    Edit: JB Nizet’s code for the other operation in his comment deserves proper code formatting, so I am pasting it here:

    public static LocalTime addWithoutOverflow(LocalTime baseTime, int minutes) {
        LocalTime maxTime = LocalTime.MAX;
        long maxNanos = ChronoUnit.NANOS.between(baseTime, maxTime);
        long nanos = Duration.ofMinutes(minutes).toNanos();
        return baseTime.plusNanos(Math.min(maxNanos, nanos));
    }