datetimejava-8java-timelocaltimedatetime-comparison

Checking if LocalDateTime falls within a time range


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?


Solution

  • 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.