在java中如何检查一个时间段与另一个时间段重叠
如何检查一个时间段是否与同一天的另一个时间段重叠 比如说,在java中如何检查一个时间段与另一个时间段重叠,java,time,Java,Time,如何检查一个时间段是否与同一天的另一个时间段重叠 比如说, 上午7:00至10:30与上午10:00至11:30重叠 上午7:00至10:30与上午8:00至9:00重叠 上午7:00至10:30与上午5:00至8:00重叠 《时代》杂志有这个。它构建得非常好,并基于JSR路线来替换损坏的Java日历API。您可能应该考虑使用它。有一个简单的解决方案,在这里表示为实用方法: public static boolean isOverlapping(Date start1, Date end1, D
《时代》杂志有这个。它构建得非常好,并基于JSR路线来替换损坏的Java日历API。您可能应该考虑使用它。有一个简单的解决方案,在这里表示为实用方法:
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);
}
这种逻辑通常出现在数据库查询中,但同样的方法适用于任何上下文
一旦你意识到这是多么简单,你首先踢自己,然后你把它放进银行 如果间隔已打开(例如,某些进程尚未完成),且结束日期可能为空:
public static boolean isOverlapping(Date start1, Date end1, Date start2, Date end2)
{
return
((null == end2) || start1.before(end2)) &&
((null == end1) || start2.before(end1)) ;
}
tl;博士
LocalTime
如果您真的想使用一天中没有日期和时区上下文的通用时间,请使用该类
验证数据,确保结束在开始之后(或相等)。一个更简单的说法是“开始不是在结束之后”
Boolean validA = ( ! startA.isAfter( stopA ) ) ;
Boolean validB = ( ! startB.isAfter( stop2B ) ) ;
根据,使用半开放的方法来定义开始是包含的,而结束是独占的时间跨度,我们可以使用以下逻辑:
(StartALocalTime
仅限于一个通用的24小时工作日。时代不可能超越午夜,也不可能回到另一个时代。没有其他的日子要考虑。验证输入以验证开始时间早于结束时间,或者它们相等(如果这符合您的业务规则)
ZoneDateTime
如果要测试时间线上的实际时刻,必须将这些时间对象调整到日期和时区的上下文中。应用一个函数来获取一个对象
关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,& 该项目现已启动,建议迁移到类 要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是 从哪里获得java.time类
- ,及以后
- 内置的李>
- 标准JavaAPI的一部分,带有捆绑实现
- Java9添加了一些次要功能和修复
- 及
- 大部分java.time功能都在中向后移植到Java6和Java7
-
- 该项目专门为Android采用了ThreeTen Backport(如上所述)
- 看
public boolean isOverlapping(Date start1, Date end1, Date start2, Date end2) {
return start1.compareTo(end2) <= 0 && end1.compareTo(start2) >= 0;
}
我们需要更多的细节——这取决于你如何存储你的时间段。是不是
java.time.Period
?一般来说,检查两个时间段是否重叠很简单-比较每个时间段的开始和结束时间。我没有存储我的时间段。我想找出重叠的时间。例如(上午7:00到10:30是重叠的,上午10:00到11:30是重叠的)这个时间是重叠的。像这样我有50双鞋的时间。所以我想用另一对验证每一对。当我说“如何存储它”时,我的意思是数据类型是什么?它会影响可能的答案(正如梦想家在他的答案中提到的,如果您正在使用Joda time,此功能已经提供)。据我们所知,句点可以是文本字符串“7:00am到10:30am”,这需要解析。或者时间可以存储为Java日期。或0.0等于1970-01-01 00:00纪元的浮点值。之前(和之后)严格地表示之前。因此,周期不是零长度:start1.before(start1)=false
@JoopEggen我想知道人们需要多长时间来评论这一点。虽然没有一个例子涵盖了这种边缘情况,但我编辑了我的答案,提出了另一种解决方案,但同样优雅(比你的:)的解决方案,如果相邻的时段被认为是重叠的,那么这种解决方案可以迎合它们;为我的==false
then;)道歉。尽管如此,第一个解决方案似乎是最合适的。我发现这真的很有帮助,谢谢!
Boolean validA = ( ! startA.isAfter( stopA ) ) ;
Boolean validB = ( ! startB.isAfter( stop2B ) ) ;
Boolean overlaps = (
( startA.isBefore( stopB ) )
&&
( stopA.isAfter( startB ) )
) ;
if( stopA.isBefore( startA ) ) { … handle error }
if( stopB.isBefore( startB ) ) { … handle error }
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
ZonedDateTime zdt = ZonedDateTime.of( today , startA , z);
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();
}