Your Name
2023-09-08 890d242d8b36aecd36c4a5f506384a08ea7b12a6
优化代码
14个文件已修改
561 ■■■■■ 已修改文件
java110-core/src/main/java/com/java110/core/smo/IComputeFeeSMO.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
java110-core/src/main/java/com/java110/core/smo/impl/ComputeFeeSMOImpl.java 143 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
java110-utils/src/main/java/com/java110/utils/util/DateUtil.java 195 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-fee/src/main/java/com/java110/fee/bmo/impl/QueryOweFeeImpl.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-fee/src/main/java/com/java110/fee/cmd/fee/ListOwnerOweFeeCmd.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-fee/src/main/java/com/java110/fee/discount/impl/LateFeeByMonthRule.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-fee/src/main/java/com/java110/fee/feeMonth/PayFeeMonthImplV1.txt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-job/src/main/java/com/java110/job/adapt/fee/asyn/impl/PayFeeDetailToMonthIImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-job/src/main/java/com/java110/job/adapt/payment/coupon/PayFeeGiftCouponAdapt.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-job/src/main/java/com/java110/job/task/fee/GenerateBillTemplate.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-report/src/main/java/com/java110/report/bmo/reportFeeMonthStatistics/impl/GetReportFeeMonthStatisticsBMOImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-report/src/main/java/com/java110/report/smo/impl/GeneratorFeeMonthStatisticsInnerServiceSMOImpl.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-report/src/main/java/com/java110/report/smo/impl/GeneratorFeeYearStatisticsInnerServiceSMOImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
springboot/src/test/java/com/java110/AppTest.java 101 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
java110-core/src/main/java/com/java110/core/smo/IComputeFeeSMO.java
@@ -146,7 +146,7 @@
     * @param toDate   结束时间
     * @return 相差月数
     */
    double dayCompare(Date fromDate, Date toDate);
//    double dayCompare(Date fromDate, Date toDate);
    /**
        *字符串的日期格式的计算
java110-core/src/main/java/com/java110/core/smo/impl/ComputeFeeSMOImpl.java
@@ -968,12 +968,12 @@
        //todo 如果 cycle 为105 则 根据缴费时间段 改写下
        if ("105".equals(feeDto.getCycle())) {
            double cycle = dayCompare(DateUtil.getDateFromStringB(feeDto.getCustomStartTime()), DateUtil.getDateFromStringB(feeDto.getCustomEndTime()));
            double cycle = DateUtil.dayCompare(DateUtil.getDateFromStringB(feeDto.getCustomStartTime()), DateUtil.getDateFromStringB(feeDto.getCustomEndTime()));
            feeDto.setCycle(cycle + "");
        }
        // todo 按结束时间缴费
        if (!StringUtil.isEmpty(feeDto.getCustEndTime())) {
            double cycle = dayCompare(feeDto.getEndTime(), DateUtil.getDateFromStringB(feeDto.getCustEndTime()));
            double cycle = DateUtil.dayCompare(feeDto.getEndTime(), DateUtil.getDateFromStringB(feeDto.getCustEndTime()));
            feeDto.setCycle(cycle + "");
        }
@@ -1734,7 +1734,7 @@
            long paymentCycle = Long.parseLong(feeDto.getPaymentCycle());
            // 当前时间 - 开始时间  = 月份
            double mulMonth = 0.0;
            mulMonth = dayCompare(startDate, billEndTime);
            mulMonth = DateUtil.dayCompare(startDate, billEndTime);
            // 月份/ 周期 = 轮数(向上取整)
            double round = 0.0;
@@ -1761,7 +1761,7 @@
            //说明欠费
            if (endDate.getTime() < targetEndDate.getTime()) {
                // 目标到期时间 - 到期时间 = 欠费月份
                oweMonth = dayCompare(endDate, targetEndDate);
                oweMonth = DateUtil.dayCompare(endDate, targetEndDate);
            }
            if (feeDto.getEndTime().getTime() > targetEndDate.getTime()) {
@@ -1778,7 +1778,7 @@
            long paymentCycle = Long.parseLong(feeDto.getPaymentCycle());
            // 当前时间 - 开始时间  = 月份
            double mulMonth = 0.0;
            mulMonth = dayCompare(startDate, billEndTime);
            mulMonth = DateUtil.dayCompare(startDate, billEndTime);
            // 月份/ 周期 = 轮数(向上取整)
            double round = 0.0;
@@ -1804,7 +1804,7 @@
            //说明欠费
            if (endDate.getTime() < targetEndDate.getTime()) {
                // 目标到期时间 - 到期时间 = 欠费月份
                oweMonth = dayCompare(endDate, targetEndDate);
                oweMonth = DateUtil.dayCompare(endDate, targetEndDate);
            }
            if (feeDto.getEndTime().getTime() > targetEndDate.getTime()) {
@@ -1821,68 +1821,69 @@
        return getTargetEndDateAndOweMonth(feeDto, null);
    }
    /**
     * 计算 两个时间点月份
     *
     * @param fromDate 开始时间
     * @param toDate   结束时间
     * @return
     */
    @Override
    public double dayCompare(Date fromDate, Date toDate) {
        double resMonth = 0.0;
        Calendar from = Calendar.getInstance();
        from.setTime(fromDate);
        Calendar to = Calendar.getInstance();
        to.setTime(toDate);
        //比较月份差 可能有整数 也会负数
        int result = to.get(Calendar.MONTH) - from.get(Calendar.MONTH);
        //比较年差
        int month = (to.get(Calendar.YEAR) - from.get(Calendar.YEAR)) * 12;
        //真实 相差月份
        result = result + month;
        //开始时间  2021-06-01  2021-08-05   result = 2    2021-08-01
        Calendar newFrom = Calendar.getInstance();
        newFrom.setTime(fromDate);
        newFrom.add(Calendar.MONTH, result);
        //如果加月份后 大于了当前时间 默认加 月份 -1 情况 12-19  21-01-10
        //这个是神的逻辑一定好好理解
        if (newFrom.getTime().getTime() > toDate.getTime()) {
            newFrom.setTime(fromDate);
            result = result - 1;
            newFrom.add(Calendar.MONTH, result);
        }
        // t1 2021-08-01   t2 2021-08-05
        long t1 = newFrom.getTime().getTime();
        long t2 = to.getTime().getTime();
        //相差毫秒
        double days = (t2 - t1) * 1.00 / (24 * 60 * 60 * 1000);
        BigDecimal tmpDays = new BigDecimal(days); //相差天数
        BigDecimal monthDay = null;
        Calendar newFromMaxDay = Calendar.getInstance();
        newFromMaxDay.set(newFrom.get(Calendar.YEAR), newFrom.get(Calendar.MONTH), 1, 0, 0, 0);
        newFromMaxDay.add(Calendar.MONTH, 1); //下个月1号
        //在当前月中 这块有问题
        if (toDate.getTime() < newFromMaxDay.getTime().getTime()) {
            monthDay = new BigDecimal(newFrom.getActualMaximum(Calendar.DAY_OF_MONTH));
            return tmpDays.divide(monthDay, 4, BigDecimal.ROUND_HALF_UP).add(new BigDecimal(result)).doubleValue();
        }
        // 上月天数
        days = (newFromMaxDay.getTimeInMillis() - t1) * 1.00 / (24 * 60 * 60 * 1000);
        tmpDays = new BigDecimal(days);
        monthDay = new BigDecimal(newFrom.getActualMaximum(Calendar.DAY_OF_MONTH));
        BigDecimal preRresMonth = tmpDays.divide(monthDay, 4, BigDecimal.ROUND_HALF_UP);
        //下月天数
        days = (t2 - newFromMaxDay.getTimeInMillis()) * 1.00 / (24 * 60 * 60 * 1000);
        tmpDays = new BigDecimal(days);
        monthDay = new BigDecimal(newFromMaxDay.getActualMaximum(Calendar.DAY_OF_MONTH));
        resMonth = tmpDays.divide(monthDay, 4, BigDecimal.ROUND_HALF_UP).add(new BigDecimal(result)).add(preRresMonth).doubleValue();
        return resMonth;
    }
//    /**
//     * 计算 两个时间点月份
//     *
//     * @param fromDate 开始时间
//     * @param toDate   结束时间
//     * @return
//     */
//
//    public double dayCompareOld(Date fromDate, Date toDate) {
//        double resMonth = 0.0;
//        Calendar from = Calendar.getInstance();
//        from.setTime(fromDate);
//        Calendar to = Calendar.getInstance();
//        to.setTime(toDate);
//        //比较月份差 可能有整数 也会负数
//        int result = to.get(Calendar.MONTH) - from.get(Calendar.MONTH);
//        //比较年差
//        int month = (to.get(Calendar.YEAR) - from.get(Calendar.YEAR)) * 12;
//
//        //真实 相差月份
//        result = result + month;
//
//        //开始时间  2021-06-01  2021-08-05   result = 2    2021-08-01
//        Calendar newFrom = Calendar.getInstance();
//        newFrom.setTime(fromDate);
//        newFrom.add(Calendar.MONTH, result);
//        //如果加月份后 大于了当前时间 默认加 月份 -1 情况 12-19  21-01-10
//        //这个是神的逻辑一定好好理解
//        if (newFrom.getTime().getTime() > toDate.getTime()) {
//            newFrom.setTime(fromDate);
//            result = result - 1;
//            newFrom.add(Calendar.MONTH, result);
//        }
//
//        // t1 2021-08-01   t2 2021-08-05
//        long t1 = newFrom.getTime().getTime();
//        long t2 = to.getTime().getTime();
//        //相差毫秒
//        double days = (t2 - t1) * 1.00 / (24 * 60 * 60 * 1000);
//        BigDecimal tmpDays = new BigDecimal(days); //相差天数
//        BigDecimal monthDay = null;
//        Calendar newFromMaxDay = Calendar.getInstance();
//        newFromMaxDay.set(newFrom.get(Calendar.YEAR), newFrom.get(Calendar.MONTH), 1, 0, 0, 0);
//        newFromMaxDay.add(Calendar.MONTH, 1); //下个月1号
//        //在当前月中 这块有问题
//        if (toDate.getTime() < newFromMaxDay.getTime().getTime()) {
//            monthDay = new BigDecimal(newFrom.getActualMaximum(Calendar.DAY_OF_MONTH));
//            return tmpDays.divide(monthDay, 4, BigDecimal.ROUND_HALF_UP).add(new BigDecimal(result)).doubleValue();
//        }
//        // 上月天数
//        days = (newFromMaxDay.getTimeInMillis() - t1) * 1.00 / (24 * 60 * 60 * 1000);
//        tmpDays = new BigDecimal(days);
//        monthDay = new BigDecimal(newFrom.getActualMaximum(Calendar.DAY_OF_MONTH));
//        BigDecimal preRresMonth = tmpDays.divide(monthDay, 4, BigDecimal.ROUND_HALF_UP);
//
//        //下月天数
//        days = (t2 - newFromMaxDay.getTimeInMillis()) * 1.00 / (24 * 60 * 60 * 1000);
//        tmpDays = new BigDecimal(days);
//        monthDay = new BigDecimal(newFromMaxDay.getActualMaximum(Calendar.DAY_OF_MONTH));
//        resMonth = tmpDays.divide(monthDay, 4, BigDecimal.ROUND_HALF_UP).add(new BigDecimal(result)).add(preRresMonth).doubleValue();
//        return resMonth;
//    }
    //手机端缴费处理
@@ -2204,15 +2205,15 @@
        // todo 如果计费起始时间 小区 递增开始时间
        if (feeDto.getEndTime().getTime() < rateStartTime.getTime()) {
            //todo 递增前的欠费
            curOweMonth = dayCompare(feeDto.getEndTime(), rateStartTime);
            curOweMonth = DateUtil.dayCompare(feeDto.getEndTime(), rateStartTime);
            oweAmountDec = curFeePrice.multiply(new BigDecimal(curOweMonth)).setScale(FeeConfigConstant.FEE_SCALE, BigDecimal.ROUND_HALF_UP);
            // todo 递增
            curOweMonth = dayCompare(rateStartTime, feeDto.getDeadlineTime());
            curOweMonth = DateUtil.dayCompare(rateStartTime, feeDto.getDeadlineTime());
        } else {
            // todo 递增
            curOweMonth = dayCompare(feeDto.getEndTime(), feeDto.getDeadlineTime());
            curOweMonth = DateUtil.dayCompare(feeDto.getEndTime(), feeDto.getDeadlineTime());
        }
        double rateMonth = dayCompare(rateStartTime, feeDto.getDeadlineTime());
        double rateMonth = DateUtil.dayCompare(rateStartTime, feeDto.getDeadlineTime());
        // todo 最大周期
        double maxCycle = Math.ceil(rateMonth / rateCycle);
java110-utils/src/main/java/com/java110/utils/util/DateUtil.java
@@ -495,6 +495,12 @@
        return maxDate;
    }
    public static int getMonthDay(Date date) {
        Calendar a = Calendar.getInstance();
        a.setTime(date);
        return a.getActualMaximum(Calendar.DAY_OF_MONTH);
    }
    public static void main(String[] args) throws ParseException {
//        SimpleDateFormat sf = new SimpleDateFormat(DateUtil.DATE_FORMATE_STRING_A);
@@ -673,60 +679,60 @@
        return Integer.parseInt(String.valueOf(between_days));
    }
    public static double dayCompare(Date fromDate, Date toDate) {
        double resMonth = 0.0;
        Calendar from = Calendar.getInstance();
        from.setTime(fromDate);
        Calendar to = Calendar.getInstance();
        to.setTime(toDate);
        //比较月份差 可能有整数 也会负数
        int result = to.get(Calendar.MONTH) - from.get(Calendar.MONTH);
        //比较年差
        int month = (to.get(Calendar.YEAR) - from.get(Calendar.YEAR)) * 12;
        //真实 相差月份
        result = result + month;
        //开始时间  2021-06-01  2021-08-05   result = 2    2021-08-01
        Calendar newFrom = Calendar.getInstance();
        newFrom.setTime(fromDate);
        newFrom.add(Calendar.MONTH, result);
        //如果加月份后 大于了当前时间 默认加 月份 -1 情况 12-19  21-01-10
        //这个是神的逻辑一定好好理解
        if (newFrom.getTime().getTime() > toDate.getTime()) {
            newFrom.setTime(fromDate);
            result = result - 1;
            newFrom.add(Calendar.MONTH, result);
        }
        // t1 2021-08-01   t2 2021-08-05
        long t1 = newFrom.getTime().getTime();
        long t2 = to.getTime().getTime();
        //相差毫秒
        double days = (t2 - t1) * 1.00 / (24 * 60 * 60 * 1000);
        BigDecimal tmpDays = new BigDecimal(days); //相差天数
        BigDecimal monthDay = null;
        Calendar newFromMaxDay = Calendar.getInstance();
        newFromMaxDay.set(newFrom.get(Calendar.YEAR), newFrom.get(Calendar.MONTH), 1, 0, 0, 0);
        newFromMaxDay.add(Calendar.MONTH, 1); //下个月1号
        //在当前月中 这块有问题
        if (toDate.getTime() < newFromMaxDay.getTime().getTime()) {
            monthDay = new BigDecimal(newFrom.getActualMaximum(Calendar.DAY_OF_MONTH));
            return tmpDays.divide(monthDay, 4, BigDecimal.ROUND_HALF_UP).add(new BigDecimal(result)).doubleValue();
        }
        // 上月天数
        days = (newFromMaxDay.getTimeInMillis() - t1) * 1.00 / (24 * 60 * 60 * 1000);
        tmpDays = new BigDecimal(days);
        monthDay = new BigDecimal(newFrom.getActualMaximum(Calendar.DAY_OF_MONTH));
        BigDecimal preRresMonth = tmpDays.divide(monthDay, 4, BigDecimal.ROUND_HALF_UP);
        //下月天数
        days = (t2 - newFromMaxDay.getTimeInMillis()) * 1.00 / (24 * 60 * 60 * 1000);
        tmpDays = new BigDecimal(days);
        monthDay = new BigDecimal(newFromMaxDay.getActualMaximum(Calendar.DAY_OF_MONTH));
        resMonth = tmpDays.divide(monthDay, 4, BigDecimal.ROUND_HALF_UP).add(new BigDecimal(result)).add(preRresMonth).doubleValue();
        return resMonth;
    }
//    public static double dayCompare(Date fromDate, Date toDate) {
//        double resMonth = 0.0;
//        Calendar from = Calendar.getInstance();
//        from.setTime(fromDate);
//        Calendar to = Calendar.getInstance();
//        to.setTime(toDate);
//        //比较月份差 可能有整数 也会负数
//        int result = to.get(Calendar.MONTH) - from.get(Calendar.MONTH);
//        //比较年差
//        int month = (to.get(Calendar.YEAR) - from.get(Calendar.YEAR)) * 12;
//
//        //真实 相差月份
//        result = result + month;
//
//        //开始时间  2021-06-01  2021-08-05   result = 2    2021-08-01
//        Calendar newFrom = Calendar.getInstance();
//        newFrom.setTime(fromDate);
//        newFrom.add(Calendar.MONTH, result);
//        //如果加月份后 大于了当前时间 默认加 月份 -1 情况 12-19  21-01-10
//        //这个是神的逻辑一定好好理解
//        if (newFrom.getTime().getTime() > toDate.getTime()) {
//            newFrom.setTime(fromDate);
//            result = result - 1;
//            newFrom.add(Calendar.MONTH, result);
//        }
//
//        // t1 2021-08-01   t2 2021-08-05
//        long t1 = newFrom.getTime().getTime();
//        long t2 = to.getTime().getTime();
//        //相差毫秒
//        double days = (t2 - t1) * 1.00 / (24 * 60 * 60 * 1000);
//        BigDecimal tmpDays = new BigDecimal(days); //相差天数
//        BigDecimal monthDay = null;
//        Calendar newFromMaxDay = Calendar.getInstance();
//        newFromMaxDay.set(newFrom.get(Calendar.YEAR), newFrom.get(Calendar.MONTH), 1, 0, 0, 0);
//        newFromMaxDay.add(Calendar.MONTH, 1); //下个月1号
//        //在当前月中 这块有问题
//        if (toDate.getTime() < newFromMaxDay.getTime().getTime()) {
//            monthDay = new BigDecimal(newFrom.getActualMaximum(Calendar.DAY_OF_MONTH));
//            return tmpDays.divide(monthDay, 4, BigDecimal.ROUND_HALF_UP).add(new BigDecimal(result)).doubleValue();
//        }
//        // 上月天数
//        days = (newFromMaxDay.getTimeInMillis() - t1) * 1.00 / (24 * 60 * 60 * 1000);
//        tmpDays = new BigDecimal(days);
//        monthDay = new BigDecimal(newFrom.getActualMaximum(Calendar.DAY_OF_MONTH));
//        BigDecimal preRresMonth = tmpDays.divide(monthDay, 4, BigDecimal.ROUND_HALF_UP);
//
//        //下月天数
//        days = (t2 - newFromMaxDay.getTimeInMillis()) * 1.00 / (24 * 60 * 60 * 1000);
//        tmpDays = new BigDecimal(days);
//        monthDay = new BigDecimal(newFromMaxDay.getActualMaximum(Calendar.DAY_OF_MONTH));
//        resMonth = tmpDays.divide(monthDay, 4, BigDecimal.ROUND_HALF_UP).add(new BigDecimal(result)).add(preRresMonth).doubleValue();
//        return resMonth;
//    }
    /**
     * 通过时间秒毫秒数判断两个时间的间隔
@@ -802,4 +808,85 @@
        return calendar.getTime();
    }
    public static boolean sameMonthDay(Date startDate,Date endDate){
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(startDate);
        Calendar endCalender = Calendar.getInstance();
        endCalender.setTime(endDate);
        if(startCalendar.get(Calendar.DAY_OF_MONTH) == endCalender.get(Calendar.DAY_OF_MONTH)){
            return true;
        }
        return false;
    }
    /**
     * 计算 fromDate 2023-01-12  toDate 2023-09-15
     * 2023-01-12--->2023-01-01        --->  2023-09-01    ------> 2023-09-15
     * fromDate ---> fromDateFirstDate --->  toDateFirstDate ----> toDate
     *
     * @param fromDate
     * @param toDate
     * @return
     */
    public static double dayCompare(Date fromDate, Date toDate) {
        //todo 需要计算三端时间 相加即可
        Date fromDateFirstDate = fromDate; // 第一个1日
        Date toDateFirstDate = toDate; // 最后一个1日
        boolean firstDay = true;
        //todo 1.0 计算 fromDateFirstDate
        Calendar fromDateCal = Calendar.getInstance();
        fromDateCal.setTime(fromDate);
        fromDateCal.set(Calendar.DAY_OF_MONTH, 1);
        if (fromDate.getTime() > fromDateCal.getTime().getTime()) {
            fromDateCal.add(Calendar.MONTH, 1);
            firstDay = false;
            fromDateFirstDate = fromDateCal.getTime();
        }
        //todo 2.0 计算 toDateFirstDate
        Calendar toDateCal = Calendar.getInstance();
        toDateCal.setTime(toDate);
        toDateCal.set(Calendar.DAY_OF_MONTH, 1);
        if (toDate.getTime() > toDateCal.getTime().getTime()) {
            toDateFirstDate = toDateCal.getTime();
        }
        // todo 3.0 计算整数月  fromDateFirstDate --->  toDateFirstDate
        Calendar from = Calendar.getInstance();
        from.setTime(fromDateFirstDate);
        Calendar to = Calendar.getInstance();
        to.setTime(toDateFirstDate);
        //比较月份差 可能有整数 也会负数
        int result = to.get(Calendar.MONTH) - from.get(Calendar.MONTH);
        //比较年差
        int month = (to.get(Calendar.YEAR) - from.get(Calendar.YEAR)) * 12;
        //真实 相差月份
        result = result + month;
        //todo 3.1  如果 fromDate 和toDate 是同一天 则直接返回整月,不再计算 4.0 和5.0
        if (DateUtil.sameMonthDay(fromDate, toDate)) {
            return firstDay ? result : result + 1;
        }
        // todo 4.0 计算 fromDate ---> fromDateFirstDate 的月份
        double days = (fromDateFirstDate.getTime() - fromDate.getTime()) * 1.00 / (24 * 60 * 60 * 1000);
        BigDecimal tmpDays = new BigDecimal(days); //相差天数
        BigDecimal monthDay = new BigDecimal(DateUtil.getMonthDay(fromDate));
        BigDecimal resMonth = tmpDays.divide(monthDay, 4, BigDecimal.ROUND_HALF_UP).add(new BigDecimal(result));
        // todo 5.0 计算  toDateFirstDate ----> toDate 月份
        days = (toDate.getTime() - toDateFirstDate.getTime()) * 1.00 / (24 * 60 * 60 * 1000);
        tmpDays = new BigDecimal(days); //相差天数
        monthDay = new BigDecimal(DateUtil.getMonthDay(toDate));
        resMonth = tmpDays.divide(monthDay, 4, BigDecimal.ROUND_HALF_UP).add(resMonth);
        return resMonth.doubleValue();
    }
}
service-fee/src/main/java/com/java110/fee/bmo/impl/QueryOweFeeImpl.java
@@ -657,32 +657,7 @@
    }
    /**
     * 计算2个日期之间相差的  以年、月、日为单位,各自计算结果是多少
     * 比如:2011-02-02 到  2017-03-02
     * 以年为单位相差为:6年
     * 以月为单位相差为:73个月
     * 以日为单位相差为:2220天
     *
     * @param fromDate
     * @param toDate
     * @return
     */
    public static double dayCompare(Date fromDate, Date toDate) {
        Calendar from = Calendar.getInstance();
        from.setTime(fromDate);
        Calendar to = Calendar.getInstance();
        to.setTime(toDate);
        long t1 = from.getTimeInMillis();
        long t2 = to.getTimeInMillis();
        double days = (t2 - t1) * 1.00 / (24 * 60 * 60 * 1000);
        BigDecimal tmpDays = new BigDecimal(days);
        BigDecimal monthDay = new BigDecimal(30);
        return tmpDays.divide(monthDay, 2, RoundingMode.HALF_UP).doubleValue();
    }
    private Map getTargetEndDateAndOweMonth(FeeDto feeDto) {
        Date targetEndDate = null;
@@ -743,7 +718,7 @@
            long paymentCycle = Long.parseLong(feeDto.getPaymentCycle());
            // 当前时间 - 开始时间  = 月份
            double mulMonth = 0.0;
            mulMonth = dayCompare(startDate, billEndTime);
            mulMonth = DateUtil.dayCompare(startDate, billEndTime);
            // 月份/ 周期 = 轮数(向上取整)
            double round = 0.0;
@@ -761,7 +736,7 @@
            //说明没有欠费
            if (endDate.getTime() < targetEndDate.getTime()) {
                // 目标到期时间 - 到期时间 = 欠费月份
                oweMonth = dayCompare(endDate, targetEndDate);
                oweMonth = DateUtil.dayCompare(endDate, targetEndDate);
            }
            if (feeDto.getEndTime().getTime() > targetEndDate.getTime()) {
service-fee/src/main/java/com/java110/fee/cmd/fee/ListOwnerOweFeeCmd.java
@@ -153,7 +153,7 @@
            if (FeeConfigDto.BILL_TYPE_EVERY.equals(tmpFeeConfigDto.getBillType())) {//直接计算 欠费金额
                computeFeePriceByRoom(feeDto);
                double month = dayCompare(endTime, DateUtil.getCurrentDate());
                double month = DateUtil.dayCompare(endTime, DateUtil.getCurrentDate());
                BigDecimal feePrice = new BigDecimal(feeDto.getFeePrice());
                feePrice = feePrice.multiply(new BigDecimal(month));
                FeeDto tmpFeeDto = new FeeDto();
@@ -255,33 +255,5 @@
        }
        feeDto.setFeePrice(feePrice);
    }
    /**
     * 计算2个日期之间相差的  以年、月、日为单位,各自计算结果是多少
     * 比如:2011-02-02 到  2017-03-02
     * 以年为单位相差为:6年
     * 以月为单位相差为:73个月
     * 以日为单位相差为:2220天
     *
     * @param fromDate
     * @param toDate
     * @return
     */
    public static double dayCompare(Date fromDate, Date toDate) {
        Calendar from = Calendar.getInstance();
        from.setTime(fromDate);
        Calendar to = Calendar.getInstance();
        to.setTime(toDate);
        long t1 = from.getTimeInMillis();
        long t2 = to.getTimeInMillis();
        double days = (t2 - t1)*1.00/ (24 * 60 * 60 * 1000);
        BigDecimal tmpDays = new BigDecimal(days);
        BigDecimal monthDay = new BigDecimal(30);
        return tmpDays.divide(monthDay, 2, RoundingMode.HALF_UP).doubleValue();
    }
}
service-fee/src/main/java/com/java110/fee/discount/impl/LateFeeByMonthRule.java
@@ -83,7 +83,7 @@
            return computeDiscountDto;
        }
        //查询费用
        Double month = computeFeeSMOImpl.dayCompare(endTime, curTime);
        Double month = DateUtil.dayCompare(endTime, curTime);
        Map feePriceAll = computeFeeSMOImpl.getFeePrice(feeDtos.get(0));
service-fee/src/main/java/com/java110/fee/feeMonth/PayFeeMonthImplV1.txt
@@ -117,7 +117,7 @@
    }
    private void doGeneratorTimeMonthData(FeeDto feeDto, PayFeeMonthOwnerDto payFeeMonthOwnerDto, Double feePrice, Date startTime, Date endTime) {
        double maxMonth = Math.ceil(computeFeeSMOImpl.dayCompare(startTime, endTime));
        double maxMonth = Math.ceil(DateUtil.dayCompare(startTime, endTime));
        if (maxMonth < 1) {
            return;
service-job/src/main/java/com/java110/job/adapt/fee/asyn/impl/PayFeeDetailToMonthIImpl.java
@@ -139,7 +139,7 @@
    private void toMonth(JSONObject businessPayFeeDetail, FeeDto feeDto, Date startTime, Date endTime, Date createTime) {
        double maxMonth = 1;
        if (!FeeDto.FEE_FLAG_ONCE.equals(feeDto.getFeeFlag())) {
            maxMonth = Math.ceil(computeFeeSMOImpl.dayCompare(startTime, endTime));
            maxMonth = Math.ceil(DateUtil.dayCompare(startTime, endTime));
        }
        if (maxMonth < 1) {
service-job/src/main/java/com/java110/job/adapt/payment/coupon/PayFeeGiftCouponAdapt.java
@@ -203,7 +203,7 @@
                }else if(CouponRuleCppsDto.FREQUENCY_MONTH.equals(couponRuleCppsDto.getGiftFrequency())){ // 每月赠送
                    startTime = DateUtil.getDateFromString(payFeeDetailPo.getStartTime(), DateUtil.DATE_FORMATE_STRING_B);
                    endTime = DateUtil.getDateFromString(payFeeDetailPo.getEndTime(), DateUtil.DATE_FORMATE_STRING_B);
                    double maxMonth = Math.ceil(computeFeeSMOImpl.dayCompare(startTime, endTime));
                    double maxMonth = Math.ceil(DateUtil.dayCompare(startTime, endTime));
                    if (maxMonth < 1) {
                        doGiftCoupon(couponRuleCppsDto, feeDto, DateUtil.getNow(DateUtil.DATE_FORMATE_STRING_B));
                        continue;
service-job/src/main/java/com/java110/job/task/fee/GenerateBillTemplate.java
@@ -227,7 +227,7 @@
        billOweFeeDto.setBillId(billDto.getBillId());
        double month = 0.0;
        if (TASK_ATTR_VALUE_DAY.equals(feeConfigDto.getBillType())) {
            month = dayCompare(feeDto.getEndTime(), billEndTime);
            month = DateUtil.dayCompare(feeDto.getEndTime(), billEndTime);
        } else {
            month = monthCompare(feeDto.getEndTime(), billEndTime);
        }
@@ -235,7 +235,7 @@
        curFeePrice = curFeePrice.multiply(new BigDecimal(month));
        billOweFeeDto.setAmountOwed(curFeePrice.doubleValue() + "");
        if (TASK_ATTR_VALUE_DAY.equals(feeConfigDto.getBillType())) {
            month = dayCompare(feeDto.getEndTime(), billEndTime);
            month = DateUtil.dayCompare(feeDto.getEndTime(), billEndTime);
        } else {
            month = monthCompare(feeDto.getEndTime(), billEndTime);
        }
@@ -522,30 +522,5 @@
        return month;
    }
    /**
     * 计算2个日期之间相差的  以年、月、日为单位,各自计算结果是多少
     * 比如:2011-02-02 到  2017-03-02
     * 以年为单位相差为:6年
     * 以月为单位相差为:73个月
     * 以日为单位相差为:2220天
     *
     * @param fromDate
     * @param toDate
     * @return
     */
    public static double dayCompare(Date fromDate, Date toDate) {
        Calendar from = Calendar.getInstance();
        from.setTime(fromDate);
        Calendar to = Calendar.getInstance();
        to.setTime(toDate);
        long t1 = from.getTimeInMillis();
        long t2 = to.getTimeInMillis();
        double days = (t2 - t1) * 1.00 / (24 * 60 * 60 * 1000);
        BigDecimal tmpDays = new BigDecimal(days);
        BigDecimal monthDay = new BigDecimal(30);
        return tmpDays.divide(monthDay, 2, RoundingMode.HALF_UP).doubleValue();
    }
}
service-report/src/main/java/com/java110/report/bmo/reportFeeMonthStatistics/impl/GetReportFeeMonthStatisticsBMOImpl.java
@@ -911,7 +911,7 @@
            startTime = (Date) paramIn.get("startTime");
            endTime = (Date) paramIn.get("endTime");
            BigDecimal money = (BigDecimal) paramIn.get("oweAmount");
            double month = Math.ceil(computeFeeSMOImpl.dayCompare(startTime, endTime));
            double month = Math.ceil(DateUtil.dayCompare(startTime, endTime));
            if (month < 1) {
                paramIn.put("btAmount", 0);
                paramIn.put("bfAmount", 0);
@@ -924,7 +924,7 @@
            if (startTime.getTime() < curStart.getTime()) {
                BigDecimal btAmountDec = monthAmount.multiply(new BigDecimal(curMonth)).setScale(2, BigDecimal.ROUND_HALF_EVEN);
                paramIn.put("btAmount", btAmountDec.doubleValue());
                double preMonth = Math.ceil(computeFeeSMOImpl.dayCompare(startTime, curStart));
                double preMonth = Math.ceil(DateUtil.dayCompare(startTime, curStart));
                BigDecimal bfAmountDec = monthAmount.multiply(new BigDecimal(preMonth)).setScale(2, BigDecimal.ROUND_HALF_EVEN);
                paramIn.put("bfAmount", bfAmountDec.doubleValue());
                continue;
service-report/src/main/java/com/java110/report/smo/impl/GeneratorFeeMonthStatisticsInnerServiceSMOImpl.java
@@ -591,7 +591,7 @@
            return feePriceDec.subtract(hisDayDec).setScale(FeeConfigConstant.FEE_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue();
        }
        month = computeFeeSMOImpl.dayCompare(curDate, tmpReportFeeDto.getDeadlineTime());
        month = DateUtil.dayCompare(curDate, tmpReportFeeDto.getDeadlineTime());
        if (month < 0) {
            return 0;
        }
@@ -641,9 +641,9 @@
        double month = 0.0;
        if (tmpReportFeeDto.getDeadlineTime().getTime() < curDate.getTime()) {
            month = computeFeeSMOImpl.dayCompare(tmpReportFeeDto.getEndTime(), tmpReportFeeDto.getDeadlineTime());
            month = DateUtil.dayCompare(tmpReportFeeDto.getEndTime(), tmpReportFeeDto.getDeadlineTime());
        } else {
            month = computeFeeSMOImpl.dayCompare(tmpReportFeeDto.getEndTime(), curDate);
            month = DateUtil.dayCompare(tmpReportFeeDto.getEndTime(), curDate);
        }
        BigDecimal curDegree = new BigDecimal(month);
        return curDegree.multiply(feePriceDec).setScale(FeeConfigConstant.FEE_SCALE, BigDecimal.ROUND_HALF_EVEN).doubleValue();
@@ -697,7 +697,7 @@
        if (FeeDto.FEE_FLAG_ONCE.equals(tmpReportFeeDto.getFeeFlag())) {
            receivableAmount = tmpReportFeeDto.getFeePrice();
        } else {
            double month = computeFeeSMOImpl.dayCompare(tmpReportFeeDto.getEndTime(), curMonthDate.getTime());
            double month = DateUtil.dayCompare(tmpReportFeeDto.getEndTime(), curMonthDate.getTime());
            BigDecimal curDegree = new BigDecimal(month);
            receivableAmount = curDegree.multiply(new BigDecimal(tmpReportFeeDto.getFeePrice())).setScale(FeeConfigConstant.FEE_SCALE, BigDecimal.ROUND_HALF_EVEN).doubleValue();
        }
@@ -839,7 +839,7 @@
        if (belongCurMonth(tmpReportFeeDto.getEndTime())
                && !belongCurMonth(endTime)) {
            //算天数
            double month = computeFeeSMOImpl.dayCompare(tmpReportFeeDto.getEndTime(), DateUtil.getNextMonthFirstDate());
            double month = DateUtil.dayCompare(tmpReportFeeDto.getEndTime(), DateUtil.getNextMonthFirstDate());
            BigDecimal curDegree = new BigDecimal(month);
            return curDegree.multiply(feePriceDec).setScale(FeeConfigConstant.FEE_SCALE, BigDecimal.ROUND_HALF_EVEN).doubleValue();
        }
@@ -847,7 +847,7 @@
        if (!belongCurMonth(tmpReportFeeDto.getEndTime())
                && belongCurMonth(endTime)) {
            //算天数
            double month = computeFeeSMOImpl.dayCompare(DateUtil.getFirstDate(), maxEndDate);
            double month = DateUtil.dayCompare(DateUtil.getFirstDate(), maxEndDate);
            BigDecimal curDegree = new BigDecimal(month);
            return curDegree.multiply(feePriceDec).setScale(FeeConfigConstant.FEE_SCALE, BigDecimal.ROUND_HALF_EVEN).doubleValue();
        }
@@ -860,7 +860,7 @@
                || tmpReportFeeDto.getDeadlineTime().getTime() < nowTime.getTime()) {
            return 0.0;
        }
        double month = computeFeeSMOImpl.dayCompare(tmpReportFeeDto.getDeadlineTime(), tmpReportFeeDto.getEndTime());
        double month = DateUtil.dayCompare(tmpReportFeeDto.getDeadlineTime(), tmpReportFeeDto.getEndTime());
        month = Math.ceil(month);
        if (month == 0) {
@@ -909,7 +909,7 @@
        if (belongCurMonth(tmpReportFeeDto.getEndTime())
                && !belongCurMonth(maxEndDate)) {
            //算天数
            double month = computeFeeSMOImpl.dayCompare(tmpReportFeeDto.getEndTime(), DateUtil.getNextMonthFirstDate());
            double month = DateUtil.dayCompare(tmpReportFeeDto.getEndTime(), DateUtil.getNextMonthFirstDate());
            BigDecimal curDegree = new BigDecimal(month);
            return curDegree.multiply(feePriceDec).setScale(FeeConfigConstant.FEE_SCALE, BigDecimal.ROUND_HALF_EVEN).doubleValue();
        }
@@ -917,7 +917,7 @@
        if (!belongCurMonth(tmpReportFeeDto.getEndTime())
                && belongCurMonth(maxEndDate)) {
            //算天数
            double month = computeFeeSMOImpl.dayCompare(DateUtil.getFirstDate(), maxEndDate);
            double month = DateUtil.dayCompare(DateUtil.getFirstDate(), maxEndDate);
            BigDecimal curDegree = new BigDecimal(month);
            return curDegree.multiply(feePriceDec).setScale(FeeConfigConstant.FEE_SCALE, BigDecimal.ROUND_HALF_EVEN).doubleValue();
        }
service-report/src/main/java/com/java110/report/smo/impl/GeneratorFeeYearStatisticsInnerServiceSMOImpl.java
@@ -439,7 +439,7 @@
        if (endYear == curYear) {
            try {
                cycleMonth = computeFeeSMOImpl.dayCompare(DateUtil.getDateFromString(curYear + "-01-01", DateUtil.DATE_FORMATE_STRING_B), tmpReportFeeDto.getConfigEndTime());
                cycleMonth = DateUtil.dayCompare(DateUtil.getDateFromString(curYear + "-01-01", DateUtil.DATE_FORMATE_STRING_B), tmpReportFeeDto.getConfigEndTime());
            } catch (ParseException e) {
                logger.error("计算 时间差出错", e);
                cycleMonth = configEndTime.get(Calendar.MONTH) + 1;
springboot/src/test/java/com/java110/AppTest.java
@@ -11,6 +11,7 @@
import org.junit.Test;
import java.math.BigDecimal;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
@@ -19,25 +20,26 @@
/**
 * Unit test for simple App.
 */
public class AppTest
{
public class AppTest {
    /**
     * Rigorous Test :-)
     */
    @Test
    public void should()
    {
    public void should() {
//解密
        FeeDto feeDto = new FeeDto();
        feeDto.setStartTime(DateUtil.getDateFromStringB("2023-01-01"));
        feeDto.setEndTime(DateUtil.getDateFromStringB("2023-01-12"));
        feeDto.setPrepaymentPeriod("20");
        feeDto.setState(FeeDto.STATE_DOING);
        feeDto.setConfigEndTime(DateUtil.getDateFromStringB("2050-01-01"));
        feeDto.setFeeFlag(FeeDto.FEE_FLAG_CYCLE);
        feeDto.setPaymentCd("1200");
        feeDto.setPaymentCycle("12");
        getTargetEndDateAndOweMonth(feeDto,null);
//        FeeDto feeDto = new FeeDto();
//        feeDto.setStartTime(DateUtil.getDateFromStringB("2023-01-01"));
//        feeDto.setEndTime(DateUtil.getDateFromStringB("2023-01-12"));
//        feeDto.setPrepaymentPeriod("20");
//        feeDto.setState(FeeDto.STATE_DOING);
//        feeDto.setConfigEndTime(DateUtil.getDateFromStringB("2050-01-01"));
//        feeDto.setFeeFlag(FeeDto.FEE_FLAG_CYCLE);
//        feeDto.setPaymentCd("1200");
//        feeDto.setPaymentCycle("12");
//        getTargetEndDateAndOweMonth(feeDto,null);
// 0.3667 0.3226
        double month = dayCompare(DateUtil.getDateFromStringB("2023-01-12"), DateUtil.getDateFromStringB("2023-09-15"));
        System.out.println("month=" + month);
    }
    public Map getTargetEndDateAndOweMonth(FeeDto feeDto, OwnerCarDto ownerCarDto) {
@@ -188,7 +190,78 @@
        return endDate.getTime();
    }
    /**
     * 计算 fromDate 2023-01-12  toDate 2023-09-15
     * 2023-01-12--->2023-01-01        --->  2023-09-01    ------> 2023-09-15
     * fromDate ---> fromDateFirstDate --->  toDateFirstDate ----> toDate
     *
     * @param fromDate
     * @param toDate
     * @return
     */
    public double dayCompare(Date fromDate, Date toDate) {
        //todo 需要计算三端时间 相加即可
        Date fromDateFirstDate = fromDate; // 第一个1日
        Date toDateFirstDate = toDate; // 最后一个1日
        boolean firstDay = true;
        //todo 1.0 计算 fromDateFirstDate
        Calendar fromDateCal = Calendar.getInstance();
        fromDateCal.setTime(fromDate);
        fromDateCal.set(Calendar.DAY_OF_MONTH, 1);
        if (fromDate.getTime() > fromDateCal.getTime().getTime()) {
            fromDateCal.add(Calendar.MONTH, 1);
            firstDay = false;
            fromDateFirstDate = fromDateCal.getTime();
        }
        //todo 2.0 计算 toDateFirstDate
        Calendar toDateCal = Calendar.getInstance();
        toDateCal.setTime(toDate);
        toDateCal.set(Calendar.DAY_OF_MONTH, 1);
        if (toDate.getTime() > toDateCal.getTime().getTime()) {
            toDateFirstDate = toDateCal.getTime();
        }
        // todo 3.0 计算整数月  fromDateFirstDate --->  toDateFirstDate
        Calendar from = Calendar.getInstance();
        from.setTime(fromDateFirstDate);
        Calendar to = Calendar.getInstance();
        to.setTime(toDateFirstDate);
        //比较月份差 可能有整数 也会负数
        int result = to.get(Calendar.MONTH) - from.get(Calendar.MONTH);
        //比较年差
        int month = (to.get(Calendar.YEAR) - from.get(Calendar.YEAR)) * 12;
        //真实 相差月份
        result = result + month;
        //todo 3.1  如果 fromDate 和toDate 是同一天 则直接返回整月,不再计算 4.0 和5.0
        if (DateUtil.sameMonthDay(fromDate, toDate)) {
            return firstDay ? result : result + 1;
        }
        // todo 4.0 计算 fromDate ---> fromDateFirstDate 的月份
        double days = (fromDateFirstDate.getTime() - fromDate.getTime()) * 1.00 / (24 * 60 * 60 * 1000);
        BigDecimal tmpDays = new BigDecimal(days); //相差天数
        BigDecimal monthDay = new BigDecimal(DateUtil.getMonthDay(fromDate));
        BigDecimal resMonth = tmpDays.divide(monthDay, 4, BigDecimal.ROUND_HALF_UP).add(new BigDecimal(result));
        // todo 5.0 计算  toDateFirstDate ----> toDate 月份
        days = (toDate.getTime() - toDateFirstDate.getTime()) * 1.00 / (24 * 60 * 60 * 1000);
        tmpDays = new BigDecimal(days); //相差天数
        monthDay = new BigDecimal(DateUtil.getMonthDay(toDate));
        resMonth = tmpDays.divide(monthDay, 4, BigDecimal.ROUND_HALF_UP).add(resMonth);
        return resMonth.doubleValue();
    }
    public double dayCompare1(Date fromDate, Date toDate) {
        double resMonth = 0.0;
        Calendar from = Calendar.getInstance();
        from.setTime(fromDate);