28

如何检查一个时间段与同一天的另一个时间段重叠。

例如,

  1. 上午 7:00 至上午 10:30 与上午 10:00 至上午 11:30 重叠
  2. 上午 7:00 至上午 10:30 与上午 8:00 至上午 9:00 重叠
  3. 上午 7:00 到上午 10:30 与上午 5:00 到上午 8:00 重叠
4

5 回答 5

43

有一个简单的解决方案,在这里表示为实用方法:

public static boolean isOverlapping(Date start1, Date end1, Date start2, Date end2) {
    return start1.before(end2) && start2.before(end1);
}

此代码要求在两个周期之间共享至少一毫秒才能返回true

如果相邻时间段被认为“重叠”(例如 10:00-10:30 和 10:30-11:00),则需要稍微调整逻辑:

public static boolean isOverlapping(Date start1, Date end1, Date start2, Date end2) {
    return !start1.after(end2) && !start2.after(end1);
}

这种逻辑更常出现在数据库查询中,但同样的方法适用于任何上下文。

一旦你意识到它是多么简单,你首先会踢自己,然后把它放在银行里!

于 2013-06-14T11:57:34.140 回答
19
于 2017-04-16T04:13:36.210 回答
5

如果间隔已打开(例如,某些进程尚未完成)并且结束日期可能为空:

public static boolean isOverlapping(Date start1, Date end1, Date start2, Date end2)
{
    return
            ((null == end2) || start1.before(end2)) &&
            ((null == end1) || start2.before(end1)) ;
}
于 2016-11-18T11:44:09.773 回答
4

JOda Time. 它构建得非常好,并且在 JSR 路线上取代了损坏的 Java 日历 API。您可能应该考虑使用它。

于 2013-06-14T11:49:05.290 回答
2

编辑:

这是工作方法:

public boolean isOverlapping(Date start1, Date end1, Date start2, Date end2) {
    return start1.compareTo(end2) <= 0 && end1.compareTo(start2) >= 0;
}

这是每个人都可以尝试的证据:

@Test
public void isOverlapping_base() {
    Assert.assertTrue(isOverlapping(getDate(2014, 1, 1),
            getDate(2014, 3, 31), getDate(2014, 1, 2),
            getDate(2014, 4, 1)));
    
    Assert.assertTrue(isOverlapping(getDate(2014, 1, 2),
            getDate(2014, 4, 1), getDate(2014, 1, 1),
            getDate(2014, 3, 31)));
    
    Assert.assertTrue(isOverlapping(getDate(2014, 1, 1),
            getDate(2014, 4, 1), getDate(2014, 1, 2),
            getDate(2014, 3, 31)));
    
    Assert.assertTrue(isOverlapping(getDate(2014, 1, 2),
            getDate(2014, 3, 31), getDate(2014, 1, 1),
            getDate(2014, 4, 1)));
    
    Assert.assertFalse(isOverlapping(getDate(2014, 1, 1),
            getDate(2014, 1, 31), getDate(2014, 3, 1),
            getDate(2014, 3, 31)));
    
    Assert.assertFalse(isOverlapping(getDate(2014, 3, 1),
            getDate(2014, 3, 31), getDate(2014, 1, 1),
            getDate(2014, 1, 31)));
}

Date getDate(int year, int month, int date) {
    Calendar working = Calendar.getInstance();
    working.set(year, month - 1, date, 0, 0, 0); 
    working.set(Calendar.MILLISECOND, 0);
    return working.getTime();
}
于 2018-01-11T07:26:35.483 回答