如何在java中检查一个时间段是否与另一个时间段重叠tl;博士LocalTimeZonedDateTime关于 java.time

2022-09-01 12:31:46

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

例如

  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

答案 1

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

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);
}

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

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


答案 2

tl;博士

( startA.isBefore( stopB ) ) && ( stopA.isAfter( startB ) ) 

LocalTime

如果确实要使用没有日期和时区上下文的通用时间,请使用 LocalTime 类。

LocalTime startA = LocalTime.of( 7 , 0 );
LocalTime stopA = LocalTime.of( 10 , 30 );

LocalTime startB = LocalTime.of( 10 , 0 );
LocalTime stop2B = LocalTime.of( 11 , 30 );

验证数据,确保结尾在开头之后(或等于)。更簡短的說法是“開始不是結束後”。

Boolean validA = ( ! startA.isAfter( stopA ) ) ;
Boolean validB = ( ! startB.isAfter( stop2B ) ) ;

根据Meno Hochschild的这个答案,使用半开方法来定义一个时间跨度,其中开头是包容性的,而结尾是排他性的,我们可以使用以下逻辑:

(StartA < EndB) 和 (EndA > StartB)

Boolean overlaps = ( 
    ( startA.isBefore( stopB ) ) 
    && 
    ( stopA.isAfter( startB ) ) 
) ;

请注意,这仅限于单个通用的 24 小时工作日。时代不能超过午夜,不能绕到另一个。没有其他日子可以考虑。验证您的输入以验证开始时间是否在结束之前,或者它们是否相等(如果这符合您的业务规则)。LocalTime

if( stopA.isBefore( startA ) ) { … handle error  } 

if( stopB.isBefore( startB ) ) { … handle error  } 

ZonedDateTime

如果要测试时间轴上的实际时刻,则必须将这些时间对象调整为日期和时区的上下文。应用 ZoneId 以获取 ZonedDateTime 对象。

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
ZonedDateTime zdt = ZonedDateTime.of( today , startA , z);

Table of all date-time types in Java, both modern and legacy


关于 java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧日期时间类,如java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在处于维护模式,建议迁移到 java.time 类。

要了解更多信息,请参阅 Oracle 教程。搜索 Stack Overflow 以获取许多示例和解释。规格是JSR 310

从哪里获取 java.time 类?

ThreeTen-Extra 项目通过其他类扩展了 java.time。这个项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuarter


推荐