1

I want to create a method that tells me if i'm between two hours (even if I choose hours from different days) For example:

Current time: 20:00, start: 21:00, end: 23:00 -> returns false
Current time: 22:00, start: 21:00, end: 23:00 -> returns true
Current time: 01:00, start: 21:00, end: 8:00 -> returns true
Current time: 22:00, start: 21:00, end: 20:00 -> returns true
Current time: 05:00, start: 21:00, end: 4:00 -> returns false

Is there any simple and clean way to do this?

  • 2
    look at [isBefore](https://docs.oracle.com/javase/8/docs/api/java/time/LocalTime.html#isBefore-java.time.LocalTime-) and [isAfter](https://docs.oracle.com/javase/8/docs/api/java/time/LocalTime.html#isAfter-java.time.LocalTime-) – Youcef LAIDANI Nov 18 '20 at 16:31
  • `I want to create a method that tells me if i'm between two hours (even if I choose hours from different days)...Is there any simple and clean way to do this?` - Without the date, the cleanest way is to return `true` in all cases. – Arvind Kumar Avinash Nov 18 '20 at 16:33
  • I chose to close as a duplicate even though the answer given here is better than the accepted answer under the other question. Over there there’s a more thorough [answer by Basil Bourque](https://stackoverflow.com/a/39712175/5772882) that I believe deserves your attention. – Ole V.V. Nov 19 '20 at 03:51

1 Answers1

1

You can use LocalTime for that (since you want it to be independent of the day or timezones or anything like that). It has isBefore and similar methods that makes this very simple:

public static boolean isBetween(LocalTime before, LocalTime candidate, LocalTime after) {
    return before.isBefore(candidate) && candidate.isBefore(after);
}

Usage is simple:

System.out.println(isBetween(LocalTime.of(20, 0), LocalTime.now(), LocalTime.of(23, 0));

Edit

It seems that you actually want another logic that allows for ranges that overlap a day. Your example for this is:

Current time: 01:00, start: 21:00, end: 8:00 -> returns true

To make this possible I would introduce the following changes.

First, you can detect this event by simply checking whether before is actually before after. If not, then you have this case. Next, identify whether now is on the day of before or after and then reset the other to either the beginning of the day (00:00) or the end of the day (23:59) respectively. Afterwards you can compare again by normal means as shown before:

public static boolean isBetween(LocalTime before, LocalTime candidate, LocalTime after) {
    // Special handling for day-overlap
    if (before.isAfter(after)) {
        // Identify on which day candidate is and reset the other
        if (before.isBefore(candidate)) {
            after = LocalTime.MAX;
        } else {
            before = LocalTime.MIN;
        }
    }

    return before.isBefore(candidate) && candidate.isBefore(after);
}
Zabuzard
  • 25,064
  • 8
  • 58
  • 82
  • It doesnt work for third case :) It should be something like this ```if (endTime.isBefore(startTime)) { return (now.isAfter(startTime) && now.isBefore(LocalTime.of(23, 59, 59))) || (now.isBefore(endTime) && now.isAfter(LocalTime.of(0, 0, 0))); } return now.isAfter(startTime) && now.isBefore(endTime);``` –  Nov 20 '20 at 13:21
  • @domvnski That is because your third case doesnt obey logic and the rules you laid out. `21:00` is not before `01:00`. I get your intention but this is incorrect logic if you want to ignore days. So you actually do want to have day-logic in this case. – Zabuzard Nov 20 '20 at 14:02
  • @domvnski I have edited my post accordingly to show you a clean and readable way of doing it. – Zabuzard Nov 20 '20 at 14:16