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 LocalDateTime
verification, they fail, as they somehow return true. I've started debugging, and can't quite believe my eyes, which explains the true && false
check:
For whatever reason, evaluating the two statements separately shows the expected behaviour, but combining them, returns true.
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 afterroundedStartTime
or
time
equals
roundedStartTime
and
time
is beforeroundedEndTime
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());
}