javavalidationdebugginglocaltime

Comparing LocalTime returns true, even tho debugger evaluates to false


So, I am currently working on a function that checks if a given LocalTime is inside a range. All good, and the equivalent for LocalDateTime works without an issue.

So, my code right now looks like this:

    public boolean isInRange(LocalTime time){
        return (time.isAfter(roundedStartTime.toLocalTime())) || time.equals(roundedStartTime.toLocalTime()) &&
            time.isBefore(roundedEndTime.toLocalTime());
    }

It has some specifics for my business logic, but thats not part of the issue. I also have accompanying junit tests, that check if the logic works as intended. Again, the inRange(LocalDateTime time) function works flawlessly.

But using my tests, with the same time I use for the LocalDateTimeverification, they fail, as they somehow return true. I've started debugging, and can't quite believe my eyes, which explains the true && falsecheck:

enter image description here

For whatever reason, evaluating the two statements separately shows the expected behaviour, but combining them, returns true.


Solution

  • Your function of

        public boolean isInRange(LocalTime time){
            return (time.isAfter(roundedStartTime.toLocalTime())) || time.equals(roundedStartTime.toLocalTime()) &&
                time.isBefore(roundedEndTime.toLocalTime());
        }
    

    Is checking whether

    time is after roundedStartTime

    or

    time equals roundedStartTime

    and

    time is before roundedEndTime

    Looking at the Java operator precedence table we can conclude that && has a precedence of 4, while || has a precedence of 3. As a result, your condition is checking whether (time equals roundedStartTime and before roundedEndTime) or (time is after roundedStartTime).

    So, when your time is after roundedStartTime and after roundedEndTime, that is, it's later than the whole range, the condition will still be evaluated to true, because the first operand of || evaluated to true. To fix it, you will need to wrap paranthesis around your ||, so your logical expression will evaluate to

    (time >= roundedStartTime) and (time < roundedEndTime)

    Fix:

        public boolean isInRange(LocalTime time){
            return ((time.isAfter(roundedStartTime.toLocalTime())) || time.equals(roundedStartTime.toLocalTime())) &&
                time.isBefore(roundedEndTime.toLocalTime());
        }