首页 > 解决方案 > 确定两个循环时间是否重叠

问题描述

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

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

当结束时间严格在开始时间之后时,我在网上找到了一些答案。我怎样才能解决这个问题?我正在使用这个 StackOverflow 解决方案,但它不能完全正常工作:确定两个日期范围是否重叠

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

这是调试输出,它应该返回 True 但它不是: 调试输出

标签: androidkotlinmathtimecalendar

解决方案


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

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

我使用LocalTimejava.time(现代 Java 日期和时间 API)作为表示一天中某个时间的明显类。您在代码中使用的Calendar类设计不良且早已过时,仅适用于一天中的某个时间,因为它必须包含一个日期,这可能会干扰比较,但没有检查这是否是您的代码没有的原因t 给出预期的结果。

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

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

  • 在 Java 8 及更高版本以及更新的 Android 设备(从 API 级别 26 开始)中,现代 API 是内置的。
  • 在非 Android Java 6 和 7 中获得 ThreeTen Backport,现代类的后向端口(ThreeTen 用于 JSR 310;请参阅底部的链接)。
  • 在较旧的 Android 上,要么使用脱糖,要么使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。在后一种情况下,请确保您从org.threeten.bp子包中导入日期和时间类。

链接


推荐阅读