请假时间计算方式java_java计算两段时间的重复天数

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

大概有三种思路:

一、常规思路

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

二、非常规思路

再来看看非常规思路,第一种的缺点是逻辑较为复杂,容易出漏洞。那有没有逻辑简单的方法呢?其实我们可以这样,将月份范围内的所有日期全部放到一个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);}

e4401de979c6de4b3727c9b479ec1cb8.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值