Checking if LocalDateTime falls within a time range

Rk R Bairi picture Rk R Bairi · Oct 25, 2017 · Viewed 8.9k times · Source

I have a time A which should fall within 90 minutes range of timeB (before and after).

Example: if timeB is 4:00 pm , time A should be between 2:30pm (-90) to 5:30pm (+90)

Tried the following :

if(timeA.isAfter(timeB.minusMinutes(90)) || timeA.isBefore(timeB.plusMinutes(90))) {
    return isInRange;   
}

Can you help me whats wrong with the logic here?

Answer

user7605325 picture user7605325 · Oct 26, 2017

As @JB Nizet said in the comments, you're using the OR operator (||).
So you're testing if A is after B - 90 OR A is before B + 90. If only one of the conditions is satisfied, it returns true.

To check if A is in the range, both conditions must be satisfied, so you must use the AND operator (&&):

if (timeA.isAfter(timeB.minusMinutes(90)) && timeA.isBefore(timeB.plusMinutes(90))) {
    return isInRange;   
}

But the code above doesn't return true if A is exactly 90 minutes before or after B. If you want it to return true when the difference is also exactly 90 minutes, you must change the condition to check this:

// lower and upper limits
LocalDateTime lower = timeB.minusMinutes(90);
LocalDateTime upper = timeB.plusMinutes(90);
// also test if A is exactly 90 minutes before or after B
if ((timeA.isAfter(lower) || timeA.equals(lower)) && (timeA.isBefore(upper) || timeA.equals(upper))) {
    return isInRange;
}

Another alternative is to use a java.time.temporal.ChronoUnit to get the difference between A and B in minutes, and check its value:

// get the difference in minutes
long diff = Math.abs(ChronoUnit.MINUTES.between(timeA, timeB));
if (diff <= 90) {
    return isInRange;
}

I used Math.abs because the difference can be negative if A is after B (so it's adjusted to be a positive number). Then I check if the difference is less than (or equal) to 90 minutes. You can change it to if (diff < 90) if you want to exclude the "equals to 90 minutes" case.


There's a difference between the approaches.

ChronoUnit rounds the difference. e.g. If A is 90 minutes and 59 seconds after B, the difference will be rounded to 90 minutes and if (diff <= 90) will be true, while using isBefore and equals will return false.