java计算两段时间的重复天数

原创  郑建华   2020-12-02   83人阅读  0 条评论

    最近在做一个功能,需要统计请假天数,按月统计。而实际的请假数据就包括跨月的情况,所以就出现一个这样的问题。要计算本月内的请假天数。实际上就是求两个时间段内的重复天数。

    大概有三种思路:

    一、常规思路

    以程序员的常规思维来看,计算两个时间段内的重复天数,分为多种情况。包括 包含、相交、相离 另外还需要处理边界值。每种情况又有细分,比如包含,如果是请假范围包含月份范围,则取月份范围。如果月份范围包括请假范围,则直接取请假范围。这样一看,逻辑思考上就较为复杂,写出来的代码阅读性就不高,容易出现纰露。


    二、非常规思路

    再来看看非常规思路,第一种的缺点是逻辑较为复杂,容易出漏洞。那有没有逻辑简单的方法呢?其实我们可以这样,将月份范围内的所有日期全部放到一个list中,然后遍历这个list,每个日期元素在另一个时间段内,则说明当前日期重复。累计计数即可。这种方案,逻辑较为简单,也不会出现什么纰漏,然而却是有一个缺陷,性能不行!如果时间范围大了,用这种方式,岂不是循环越来越大,如果该方法用在循环统计中,就更加损耗性能。


    三、进阶思路

    那有没有既便于理解,逻辑简单,又比较高性能的方案呢?我们可以用,两个时间段中 较早的结束时间减去较晚的开始时间,这样得到的正数的天数+1就是重复的天数。如果得到的天数小于0则说明两个时间段不重复。是不是非常简单呢!

/**
 * 判断两个时间段的重叠天数
 * @param startDate1
 * @param endDate1
 * @param startDate2
 * @param endDate2
 * @return
 */
public static long overLappingDayCount(LocalDate startDate1,LocalDate endDate1,LocalDate startDate2,LocalDate endDate2){
    long dayCount=0l;
    Boolean startBeforeFlag=startDate1.isBefore(startDate2);
    Boolean endBeforeFlag=endDate1.isBefore(endDate2);
    // 比较开始时间
    LocalDate compareStartDate=null;
    // 比较结束时间
    LocalDate compareEndDate=null;
    // 取比较晚的开始时间
    if(startBeforeFlag){
        compareStartDate=startDate2;
    }else{
        compareStartDate=startDate1;
    }
    // 取比较早的结束时间
    if(endBeforeFlag){
        compareEndDate=endDate1;
    }else{
        compareEndDate=endDate2;
    }
    // 计算相差天数  用比较早的结束时间-比较晚的开始时间
    dayCount=DateUtils.until(compareStartDate,compareEndDate);
    // 如果相差天数小于0 则说明没有重复天数 返回0即可
    if(dayCount<0){
        return  0;
    }
    // 如果相差天数大于等于0 则 重叠天数需要+1
    dayCount++;
    return  dayCount;
}

public static void main(String[] args) {
    LocalDate startDate1=DateUtils.parseLocalDate("2020-11-01",DEFAULT_DATE_FORMAT);
    LocalDate endDate1=DateUtils.parseLocalDate("2020-11-30",DEFAULT_DATE_FORMAT);
    LocalDate startDate2=DateUtils.parseLocalDate("2020-11-02",DEFAULT_DATE_FORMAT);
    LocalDate endDate2=DateUtils.parseLocalDate("2020-12-05",DEFAULT_DATE_FORMAT);
    long dayCount=DateUtils.overLappingDayCount(startDate1,endDate1,startDate2,endDate2);
    System.out.println(dayCount);
}


image.png


本文地址:https://www.zjh336.cn/?id=2011
版权声明:本文为原创文章,版权归 郑建华 所有,欢迎分享本文,转载请保留出处!

发表评论


表情

还没有留言,还不快点抢沙发?