判断两个循环时间是否重叠

determine if two cyclic times overlap

我一直在检查重叠时间。我的日历实现允许循环或环绕时间(因此开始时间可能在结束时间之后)

例如: startTime = 3:30PM, EndTime = 3:29PM, TimeDuration = 23 hours and 59 minutes

我在网上找到的一些答案在结束时间严格晚于开始时间时有效。我怎样才能解决这个问题? 我正在使用这个 Whosebug 解决方案,但它没有完全工作:Determine Whether Two Date Ranges Overlap

在这张图片中,两个时间范围重叠,但我的植入没有正确识别它: overlapping times

这是调试输出,它应该 return 正确,但事实并非如此: debug output

如果你单独考虑时间,你的间隔集可以在 48 小时范围内:极端情况是 11:59:59PM 到 11:59:58PM 间隔,结束于下一个 23:59:58天.

本质上,这将映射到 00:00 小时到 48:00 小时。我要做的第一件事是将 AM/PM 转换为军事时间。添加检查结束和开始之间的差异是否为负数,如果是,我会在结束时间上增加 24 小时。

您现在需要找到重叠部分。

我相信这个方法可以做到。

public static boolean overlap(LocalTime start1, LocalTime end1, LocalTime start2, LocalTime end2) {
    if (start1.isAfter(end1)) { // interval 1 crosses midnight
        if (start2.isAfter(end2)) { // both intervals cross midnight, so they overlap at midnight
            return true;
        }
        // Swap the intervals so interval 1 does not cross midnight
        return overlap(start2, end2, start1, end1);
    }
    
    // Now we know that interval 1 cannot cross midnight
    if (start2.isAfter(end2)) { // Interval 2 crosses midnight
        return start2.isBefore(end1) || end2.isAfter(start1);
    } else { // None of the intervals crosses midnight
        return start2.isBefore(end1) && end2.isAfter(start1);
    }
}

为了演示,我使用了以下实用方法。

public static void demo(LocalTime start1, LocalTime end1, LocalTime start2, LocalTime end2) {
    System.out.format("Does %s - %s overlap with %s - %s? %b%n",
            start1, end1, start2, end2, overlap(start1, end1, start2, end2));
}

让我们向实用方法提供一些数据:

    demo(LocalTime.of(15, 30), LocalTime.of(15, 29), LocalTime.of(17, 0), LocalTime.of(17, 30));
    demo(LocalTime.of(9, 30), LocalTime.of(10, 0), LocalTime.of(10, 0), LocalTime.of(10, 30));
    demo(LocalTime.of(9, 30), LocalTime.of(10, 0), LocalTime.of(23, 0), LocalTime.of(10, 0));
    demo(LocalTime.of(9, 30), LocalTime.of(10, 30), LocalTime.of(10, 0), LocalTime.of(11, 0));
    demo(LocalTime.of(6, 0), LocalTime.of(18, 30), LocalTime.of(18, 0), LocalTime.of(6, 30));
    demo(LocalTime.of(6, 0), LocalTime.of(18, 0), LocalTime.of(12, 0), LocalTime.of(13, 0));
    demo(LocalTime.of(10, 0), LocalTime.of(10, 30), LocalTime.of(10, 30), LocalTime.of(9, 30));
    demo(LocalTime.of(23, 0), LocalTime.of(23, 30), LocalTime.of(23, 0), LocalTime.of(0, 0));
    demo(LocalTime.of(23, 0), LocalTime.of(1, 0), LocalTime.of(23, 30), LocalTime.of(0, 30));
    demo(LocalTime.of(22, 30), LocalTime.of(1, 30), LocalTime.of(22, 0), LocalTime.of(1, 0));
    demo(LocalTime.of(22, 0), LocalTime.of(1, 0), LocalTime.of(22, 30), LocalTime.of(1, 30));

输出:

Does 15:30 - 15:29 overlap with 17:00 - 17:30? true
Does 09:30 - 10:00 overlap with 10:00 - 10:30? false
Does 09:30 - 10:00 overlap with 23:00 - 10:00? true
Does 09:30 - 10:30 overlap with 10:00 - 11:00? true
Does 06:00 - 18:30 overlap with 18:00 - 06:30? true
Does 06:00 - 18:00 overlap with 12:00 - 13:00? true
Does 10:00 - 10:30 overlap with 10:30 - 09:30? false
Does 23:00 - 23:30 overlap with 23:00 - 00:00? true
Does 23:00 - 01:00 overlap with 23:30 - 00:30? true
Does 22:30 - 01:30 overlap with 22:00 - 01:00? true
Does 22:00 - 01:00 overlap with 22:30 - 01:30? true

我正在使用 java.time 中的 LocalTime,现代 Java 日期和时间 API,作为代表一天中时间的明显 class .您在代码中使用的 Calendar class 设计不佳且早已过时并且不适合一天中的某个时间,因为它必须包含一个日期,这可能会干扰比较,说没有检查是否这就是您的代码没有给出预期结果的原因。

问题:java.time 不需要 Android API 26 级吗?

java.time 在新旧 Android 设备上都能很好地工作。它只需要至少 Java 6.

  • 在 Java 8 和更新的 Android 设备上(从 API 级别 26)内置了现代 API。
  • 在非Android Java 6 和 7 中获取 ThreeTen Backport,现代 classes 的 backport(ThreeTen 用于 JSR 310;请参阅底部的链接) .
  • 在较旧的 Android 上使用脱糖或 ThreeTen Backport 的 Android 版本。它叫做 ThreeTenABP。在后一种情况下,请确保使用子包从 org.threeten.bp 导入日期和时间 classes。

链接