如何检查一个日期时间段是否与另一个日期时间段重叠

Joe*_*Yue 1 java time if-statement boolean localdate

所以我创建了一个名为isDateOverlapping. 它接受(所有类型LocalDate):

  • 开始日期 1
  • 结束日期 1
  • 开始日期 2
  • 结束日期 2

这个函数的作用是告诉我 2 个日期周期是否重叠。

例如,如果我有 1 个时期2019-06-15 to 2019-06-18和另一个时期来自2019-06-15 to 2019-06-12. 它将返回 true,因为 2 个日期时间段重叠。

但是我的函数似乎并不总是返回正确的答案。能否请你帮忙。

public boolean isDateOverlapping(LocalDate start1, LocalDate end1, LocalDate start2, LocalDate end2) {

    if (start1.isAfter(start2) && start2.isBefore(start1)) {
        return true;

    } else if (end1.isBefore(end2) && start1.isAfter(start2)) {
        return true;
    } else if (start1.isAfter(end1) && end2.isBefore(start2)) {
        return true;
    }

    return false;

}
Run Code Online (Sandbox Code Playgroud)

Era*_*ran 5

理解这一点的最简单方法是考虑以下 4 种可能性:

  1. 第二个区间包含第一个区间:s2 < s1 < e1 < e2
  2. 第二个区间包含第一个区间的开始:s2 < s1 < e2 < e1
  3. 第二个区间包含第一个区间的结束:s1 < s2 < e1 < e2
  4. 第二个区间包含在第一个区间中:s1 < s2 < e2 < e1

它们可以表示如下:

        1.                  2.                    3.               4.

|---------------|       |-------|                |------|        |----|     Second Interval
     |-----|                 |------|        |-------|       |-----------|  First Interval
s2   s1    e1   e2      s2   s1 e2  e1      s1  s2   e1 e2   s1  s2  e2  e1
Run Code Online (Sandbox Code Playgroud)

所有这 4 种情况的共同不变量是第二个间隔必须在第一个间隔结束之前开始,而第二个间隔必须在第一个间隔开始后结束。

这给你:

public boolean isDateOverlapping(LocalDate start1, LocalDate end1, LocalDate start2, LocalDate end2) {
    return start2.isBefore(end1) && end2.isAfter(start1); 
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果您希望您的方法在间隔在单个点重叠时返回 true,则可能需要进行一些小的更改。在这种情况下,您需要更换start2.isBefore(end1)!start2.isAfter(end1)end2.isAfter(start1)!end2.isBefore(start1)

另请注意,我假设start1 <= end1start2 <= end2. 如果情况并非总是如此,您还必须检查这一点,并在检查上述条件之前,如有必要,将 startN 与 endN 交换。