Java时段交叉计算

背景

最近接到一个需求,做表结算(每月固定日期结算一次,类似抄表),需要对仪表数据进行补录(比如:钢厂电表坏了,做报表时需要把坏了这段时间消耗的电补录进去)。数据库有一张统计表,表中有字段开始时间,结束时间。现在补录数据也有个时段,现在需要把补录的数据结算到统计表中去。

分析

因为统计表中数据很多,不止存在一个表数据,还有各种水表气表等的结算数据。实现方案是按照用户所选择的表和时段进行补录。用户选择的时段可能和库中已有表数据存在交叉时段,也有可能不存在交叉。可是怎么求交叉呢?在网上找找查查自己修改一番然后适应了需求,下面直接上干货!!

解决方案

  1. 在库中找到是否与补录进来的数据存在时段交叉
  2. 补录数据拆分到分钟级别。value = diffSecond*miniteValue
1.在数据库查询有交叉时段的数据

mapper.java

SELECT xxxxx FROM energy_data_point_statistics WHERE data_code = #{dataCode}
        and ((time_begin <![CDATA[ <= ]]> #{beginDate} and time_end >= #{endDate}) or (time_begin <![CDATA[ <= ]]> #{endDate} and time_end >= #{endDate})
        or (time_begin >= #{beginDate} and time_end <![CDATA[ <= ]]> #{endDate}) or (time_begin <![CDATA[ <= ]]> #{beginDate} and time_end >=#{beginDate}))

此处,A-B,C-D两个时段包含情况

  1. 两段不相交
  2. 包含关系
  3. 相交

XxxserviceImpl.java–计算相交时间长度

 /***
     * @Author
     * @Description 判断两个日期重合部分时间(单位 : 毫秒)
     * @Date 2021/7/19 9:52
     */
    public long countDateIntersection(String start1, String end1, String start2, String end2) {
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long s1 = 0;
        long s2 = 0;
        long e1 = 0;
        long e2 = 0;
        try {
            //标准化到1970-01-01
            s1 = sdf2.parse(start1).getTime();
            s2 = sdf2.parse(end1).getTime();
            e1 = sdf2.parse(start2).getTime();
            e2 = sdf2.parse(end2).getTime();
        } catch (ParseException e) {
            log.error("countDateIntersection--计算错误", e);
        }
        if (e1 >= s1 && e2 <= s2) {
            //s1,s2时段包含e1,e2
            return e2 - e1;
        } else if (s1 >= e1 && e2 >= s2) {
            //e1,e2时段包含s1,s2
            return s2 - s1;
        } else {
            //两者时段相交
            long ret = Math.min(s2, e2) - Math.max(s1, e1);
            return ret < 0 ? 0 : ret;
        }
    }

思考和自测耗时久,回过头去思考也就那么也回事儿~
打完收工!
如有不对,希望大家多多斧正,留言交流!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值