无论日期如何,查找小时范围是否重叠

muh*_*dto 1 java jodatime java-8

我有一组两个小时的范围

10 PM - 02 AM
01 AM - 08 AM
Run Code Online (Sandbox Code Playgroud)

无论日期如何,我都想检查它们中的任何一个是否重叠。

例如:第一个范围可能是 8 月 1 日和 2 日,而第二个范围可能是 8 月 10 日。

这是我到目前为止

private Interval createInterval(final OpeningClosingTimesEntry entry) {
    LocalDateTime openingHour = LocalDateTime.fromDateFields(entry.getOpenTime());
    LocalDateTime closingHour = LocalDateTime.fromDateFields(entry.getCloseTime());
    if(closingHour.isBefore(openingHour)){
        closingHour = closingHour.plusDays(1);
    }
    return new Interval(openingHour.toDate().getTime(), closingHour.toDate().getTime());
}

private Interval adjustSecondIntervalDay(final Interval interval1,  final Interval interval2){
    if(interval1.getEnd().getDayOfYear() > interval2.getStart().getDayOfYear()){
        DateTime start = interval2.getStart().plusDays(1);
        DateTime end = interval2.getEnd().plusDays(1);
        return new Interval(start, end);
    }
    return interval2;
}
Run Code Online (Sandbox Code Playgroud)

Oli*_*ire 5

以下是如何正确使用 Java 8 的LocalTime. 你问 Joda Time,但你说你用的是 Java 8。Joda Time 建议大多数情况下切换到 Java 8,这种情况也不例外。

由于您不关心日期,而只是想知道时间是否重叠,因此您不应该使用诸如LocalDate或 之类的东西LocalDateTime,但是LocalTime。

为了实现你的问题,我创建了一个isBetween方法来检查两个有序时间(-of-day)是否包含第三次,即使你传递到第二天。例如,21 小时介于 18 小时和 6 小时之间。

然后,一旦您拥有该实用程序方法,您只需检查两个范围中的至少一个是否包含另一个范围的边界。

我让你自己决定边界(例如 1-2 -- 2-3)。你有通用的算法,剩下的你自己做决定。

package so38810914;

import java.time.LocalTime;
import static java.util.Objects.*;

public class Question {

    public static class LocalTimeRange {

        private final LocalTime from;
        private final LocalTime to;

        public LocalTimeRange(LocalTime from, LocalTime to) {
            requireNonNull(from, "from must not be null");
            requireNonNull(to, "to must not be null");
            this.from = from;
            this.to = to;
        }

        public boolean overlaps(LocalTimeRange other) {
            requireNonNull(other, "other must not be null");
            return isBetween(other.from, this.from, this.to)
                    || isBetween(other.to, this.from, this.to)
                    || isBetween(this.from, other.from, other.to)
                    || isBetween(this.to, other.from, other.to);
        }

        private static boolean isBetween(LocalTime t, LocalTime from, LocalTime to) {
            if (from.isBefore(to)) { // same day
                return from.isBefore(t) && t.isBefore(to);
            } else { // spans to the next day.
                return from.isBefore(t) || t.isBefore(to);
            }
        }
    }

    public static void main(String[] args) {
        test( 0,  1,     2,  3,    false);
        test( 2,  3,     0,  1,    false);
        test( 0,  3,     1,  2,    true);
        test( 1,  2,     0,  3,    true);
        test( 0,  2,     1,  3,    true);
        test(12, 18,    15, 21,    true);
        test(18,  6,    21,  3,    true);
        test(21,  3,     0,  6,    true);
        test(21,  0,     3,  6,    false);

    }

    private static void test(int from1, int to1, int from2, int to2, boolean overlap) {
        LocalTimeRange range1 = new LocalTimeRange(LocalTime.of(from1, 0), LocalTime.of(to1, 0));
        LocalTimeRange range2 = new LocalTimeRange(LocalTime.of(from2, 0), LocalTime.of(to2, 0));
        boolean test = (range1.overlaps(range2)) == overlap;
        System.out.printf("[%2d-%2d] - [%2d-%2d] -> %-5b: %s%n", from1, to1, from2, to2, overlap, test?"OK":"Not OK");
    }
}
Run Code Online (Sandbox Code Playgroud)