根據連續的日期集合,獲取並截取連續的日期區間;獲取最近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;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章