根据连续的日期集合,获取并截取连续的日期区间;获取最近12个月的日期的交易记录,如果没有补0处理

根据连续的日期集合,获取并截取连续的日期区间.

业务场景:每一条记录对应一条交易记录,拿到每一条客户的交易日期,拼接成交易区间如:201801-201803,201805-201808这样的格式,中间的逗号是因为4月份该客户没有交易记录.

刚开始看到需求时,感觉代码处理起来应该不算复杂,但是等写起来的时候才发现逻辑上的处理还是蛮麻烦的,不好去判断是否有断月的情况,即便判断了还是要做复杂的月份拼接的ifelse操作去处理逻辑.最后和同事探讨了之后,复用了他之前写的一个方法,简单修改了一下就完成了这个场景代码的编写.

  1. handleInterval() 处理流水区间的主方法.sql排序拿到最早时间和最晚时间,调 2.getBetweenDate(开始时间,截止时间),得到最早月和最晚月之间的所有月份,遍历判断拼接就完事了
 /**
     * 处理流水区间
     * @param entity
     * @param applCode
     */
    private void handleInterval(BankBillMarkDto entity, String applCode) {
        List<String> timeInterval = new ArrayList<>();
        if (PRI_BUSITYPE.equals(entity.getBusiType())) {
             timeInterval = bankBillPrivateDAO.getTimeInterval(entity.getBankCardNo(), applCode);
        } else if (PUB_BUSITYPE.equals(entity.getBusiType())) {
             timeInterval = bankBillPublicDAO.getTimeInterval(entity.getBankCardNo(), applCode);
        } //遍历拿到开始时间和截止时间
        if (CollectionUtil.isNotEmpty(timeInterval)) {
            String startTime = timeInterval.get(0).replace("-", "");
            String endTime = timeInterval.get(timeInterval.size() - 1).replace("-", "");
            List<String> period = getBetweenDate(startTime, endTime);
            StringBuffer buffer = new StringBuffer();
            buffer.append(startTime);
            boolean isBroken = false;
            //循环从开始到结束的每个年月
            for (String month : period) {
                // 有没有这个月
                boolean hasMonth = false;
                //遍历取到的每个月
                for (String everyTrade : timeInterval) {
                    String tradeTime = everyTrade.replace("-", "");
                    //判断取到的月份是否缺某个月
                    if (month.substring(0, 6).equals(tradeTime)) {
                        //如果包含这个月
                        hasMonth = true;
                        if (isBroken) {
                            buffer.append(tradeTime);
                            isBroken = false;
                        }
                        //如果包含这个月, 跳出循环取到的月份
                        break;
                    }
                }
                if (!hasMonth && !isBroken) {
                    //拼接上个月
                    buffer.append("-" + getLastMonthDay(month).replace("-", "").substring(0, 6) + ",");
                    isBroken = true;
                }
            }
            String s = buffer.toString();
            if (s.endsWith(",")) {
                s = s.substring(0, s.length() - 1);
            } else {
                s = s + "-" + endTime;
            }
            entity.setTimeInterval(s);
        }
    }
  1. getBetweenDate() 获取两个日期字符串之间的日期集合,传入开始月和结束月,返回开始月和结束月之间的所有月份(考虑月份跨年的情况)
/**
     * 获取两个日期字符串之间的日期集合
     * @param startTime:String
     * @param endTime:String
     * @return list:yyyyMM
     */
    public static List<String> getBetweenDate(String startTime, String endTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
        // 声明保存日期集合
        List<String> list = new ArrayList<String>();
        try {
            // 转化成日期类型
            Date startDate = sdf.parse(startTime);
            Date endDate = sdf.parse(endTime);
            //用Calendar 进行日期比较判断
            Calendar calendar = Calendar.getInstance();
            while (startDate.getTime() <= endDate.getTime()) {
                // 把日期添加到集合
                list.add(sdf.format(startDate));
                // 设置日期
                calendar.setTime(startDate);
                //把日期增加一个月
                calendar.add(Calendar.MONTH, 1);
                // 获取增加后的日期
                startDate = calendar.getTime();
            }
        } catch (ParseException e) {
            log.error(" getBetweenDate :{} ", getExceptionMessage(e));
        }
        return list;
    }

获取最近12个月的日期的交易记录,如果没有补0处理.

业务场景:获取最近12个月某个客户的交易金额总和,如果某个月没有记录,则返回0

  1. handlerMonth() 处理最近12个月的日期的交易记录.sql查出的是有交易记录的月份和总额,这个方法就是处理没有的月份,金额补0.先调用 2.getLatest12Month()拿到系统时间最近的12个月份(包含本月),调用上个业务场景的getBetweenDate(开始月份,结束月份) 再拿到sql的开始月份和结束月份,遍历判断是否存在系统时间的月份,如果不存在则补齐该月份
private void handlerMonth(List<TotalAmountTaxDTO> totalAmountTaxList) {
        List<String> latest12Month = getLatest12Month();
        List<String> mouths = new ArrayList<>();
        for (TotalAmountTaxDTO totalAmountTaxDTO : totalAmountTaxList) {
            mouths.add(totalAmountTaxDTO.getInvoiceDate());
        }
        String startTime = latest12Month.get(0);
        String endTime = latest12Month.get(latest12Month.size() - 1);
        List<String> period = getBetweenDate(startTime, endTime);
        //循环从开始到结束的每个年月
        for (int i = 0; i < period.size(); i++) {
            //遍历取到的每个月
            //如果不包含这个月
            if (!mouths.contains(period.get(i))) {
                totalAmountTaxList.add(i, new TotalAmountTaxDTO(period.get(i), "0"));
            }
        }
    }
  1. getLatest12Month() 获取当前系统时间最近12月的年月(含当月)以及格式化月份(<10的月份前面补0)
public static List<String> getLatest12Month() {
        String[] latest12Months = new String[12];
        Calendar cal = Calendar.getInstance();
        //把当前的系统日期设置为当月1号,防止月份天数不一样的情况
        cal.set(Calendar.DAY_OF_MONTH, 1);
        for (int i = 0; i < 12; i++) {
           latest12Months[11 - i] = cal.get(Calendar.YEAR) + fillZero(cal.get(Calendar.MONTH) + 1);
            cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) - 1); //逐次往前推1个月
        }
        return Arrays.asList(latest12Months);
    }
    /**
     * 格式化月份
     */
    public static String fillZero(int i) {
        String month = "";
        if (i < 10) {
            month = "0" + i;
        } else {
            month = String.valueOf(i);
        }
        return month;
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值