在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

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

比如说,

  • 上午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, 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 ) ) ;
    
    根据,使用半开放的方法来定义开始是包含的,而结束是独占的时间跨度,我们可以使用以下逻辑:

    (StartAStartB)

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

    ZoneDateTime
    如果要测试时间线上的实际时刻,必须将这些时间对象调整到日期和时区的上下文中。应用一个函数来获取一个对象



    关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

    该项目现已启动,建议迁移到类

    要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

    从哪里获得java.time类

    • ,及以后
      • 内置的
      • 标准JavaAPI的一部分,带有捆绑实现
      • Java9添加了一些次要功能和修复
      • 大部分java.time功能都在中向后移植到Java6和Java7
      • 该项目专门为Android采用了ThreeTen Backport(如上所述)
    该项目使用其他类扩展了java.time。这个项目是java.time将来可能添加的一个试验场。您可以在此处找到一些有用的类,如、、和。

    编辑:

    工作方法如下:

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