Your Name 2 年 前
コミット
890d242d8b

+ 1 - 1
java110-core/src/main/java/com/java110/core/smo/IComputeFeeSMO.java

@@ -146,7 +146,7 @@ public interface IComputeFeeSMO {
      * @param toDate   结束时间
      * @return 相差月数
      */
-    double dayCompare(Date fromDate, Date toDate);
+//    double dayCompare(Date fromDate, Date toDate);
 
     /**
         *字符串的日期格式的计算

+ 73 - 72
java110-core/src/main/java/com/java110/core/smo/impl/ComputeFeeSMOImpl.java

@@ -968,12 +968,12 @@ public class ComputeFeeSMOImpl implements IComputeFeeSMO {
 
         //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 @@ public class ComputeFeeSMOImpl implements IComputeFeeSMO {
             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 @@ public class ComputeFeeSMOImpl implements IComputeFeeSMO {
             //说明欠费
             if (endDate.getTime() < targetEndDate.getTime()) {
                 // 目标到期时间 - 到期时间 = 欠费月份
-                oweMonth = dayCompare(endDate, targetEndDate);
+                oweMonth = DateUtil.dayCompare(endDate, targetEndDate);
             }
 
             if (feeDto.getEndTime().getTime() > targetEndDate.getTime()) {
@@ -1778,7 +1778,7 @@ public class ComputeFeeSMOImpl implements IComputeFeeSMO {
             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 @@ public class ComputeFeeSMOImpl implements IComputeFeeSMO {
             //说明欠费
             if (endDate.getTime() < targetEndDate.getTime()) {
                 // 目标到期时间 - 到期时间 = 欠费月份
-                oweMonth = dayCompare(endDate, targetEndDate);
+                oweMonth = DateUtil.dayCompare(endDate, targetEndDate);
             }
 
             if (feeDto.getEndTime().getTime() > targetEndDate.getTime()) {
@@ -1821,68 +1821,69 @@ public class ComputeFeeSMOImpl implements IComputeFeeSMO {
         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 @@ public class ComputeFeeSMOImpl implements IComputeFeeSMO {
         // 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);

+ 141 - 54
java110-utils/src/main/java/com/java110/utils/util/DateUtil.java

@@ -495,6 +495,12 @@ public class DateUtil {
         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 @@ public class DateUtil {
         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 @@ public class DateUtil {
         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();
+
+    }
 }

+ 2 - 27
service-fee/src/main/java/com/java110/fee/bmo/impl/QueryOweFeeImpl.java

@@ -657,32 +657,7 @@ public class QueryOweFeeImpl implements IQueryOweFee {
     }
 
 
-    /**
-     * 计算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 @@ public class QueryOweFeeImpl implements IQueryOweFee {
             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 @@ public class QueryOweFeeImpl implements IQueryOweFee {
             //说明没有欠费
             if (endDate.getTime() < targetEndDate.getTime()) {
                 // 目标到期时间 - 到期时间 = 欠费月份
-                oweMonth = dayCompare(endDate, targetEndDate);
+                oweMonth = DateUtil.dayCompare(endDate, targetEndDate);
             }
 
             if (feeDto.getEndTime().getTime() > targetEndDate.getTime()) {

+ 1 - 29
service-fee/src/main/java/com/java110/fee/cmd/fee/ListOwnerOweFeeCmd.java

@@ -153,7 +153,7 @@ public class ListOwnerOweFeeCmd extends Cmd {
 
             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();
@@ -256,32 +256,4 @@ public class ListOwnerOweFeeCmd extends Cmd {
 
         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();
-    }
 }

+ 1 - 1
service-fee/src/main/java/com/java110/fee/discount/impl/LateFeeByMonthRule.java

@@ -83,7 +83,7 @@ public class LateFeeByMonthRule implements IComputeDiscount {
             return computeDiscountDto;
         }
         //查询费用
-        Double month = computeFeeSMOImpl.dayCompare(endTime, curTime);
+        Double month = DateUtil.dayCompare(endTime, curTime);
 
         Map feePriceAll = computeFeeSMOImpl.getFeePrice(feeDtos.get(0));
 

+ 1 - 1
service-fee/src/main/java/com/java110/fee/feeMonth/PayFeeMonthImplV1.txt

@@ -117,7 +117,7 @@ public class PayFeeMonthImplV1 implements IPayFeeMonth {
     }
 
     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;

+ 1 - 1
service-job/src/main/java/com/java110/job/adapt/fee/asyn/impl/PayFeeDetailToMonthIImpl.java

@@ -139,7 +139,7 @@ public class PayFeeDetailToMonthIImpl implements IPayFeeDetailToMonth {
     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) {

+ 1 - 1
service-job/src/main/java/com/java110/job/adapt/payment/coupon/PayFeeGiftCouponAdapt.java

@@ -203,7 +203,7 @@ public class PayFeeGiftCouponAdapt extends DatabusAdaptImpl {
                 }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;

+ 2 - 27
service-job/src/main/java/com/java110/job/task/fee/GenerateBillTemplate.java

@@ -227,7 +227,7 @@ public class GenerateBillTemplate extends TaskSystemQuartz {
         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 @@ public class GenerateBillTemplate extends TaskSystemQuartz {
         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 @@ public class GenerateBillTemplate extends TaskSystemQuartz {
         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();
-    }
 }

+ 2 - 2
service-report/src/main/java/com/java110/report/bmo/reportFeeMonthStatistics/impl/GetReportFeeMonthStatisticsBMOImpl.java

@@ -911,7 +911,7 @@ public class GetReportFeeMonthStatisticsBMOImpl implements IGetReportFeeMonthSta
             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 @@ public class GetReportFeeMonthStatisticsBMOImpl implements IGetReportFeeMonthSta
             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;

+ 9 - 9
service-report/src/main/java/com/java110/report/smo/impl/GeneratorFeeMonthStatisticsInnerServiceSMOImpl.java

@@ -591,7 +591,7 @@ public class GeneratorFeeMonthStatisticsInnerServiceSMOImpl implements IGenerato
             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 @@ public class GeneratorFeeMonthStatisticsInnerServiceSMOImpl implements IGenerato
 
         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 @@ public class GeneratorFeeMonthStatisticsInnerServiceSMOImpl implements IGenerato
         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 @@ public class GeneratorFeeMonthStatisticsInnerServiceSMOImpl implements IGenerato
         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 @@ public class GeneratorFeeMonthStatisticsInnerServiceSMOImpl implements IGenerato
         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 @@ public class GeneratorFeeMonthStatisticsInnerServiceSMOImpl implements IGenerato
                 || 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 @@ public class GeneratorFeeMonthStatisticsInnerServiceSMOImpl implements IGenerato
         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 @@ public class GeneratorFeeMonthStatisticsInnerServiceSMOImpl implements IGenerato
         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();
         }

+ 1 - 1
service-report/src/main/java/com/java110/report/smo/impl/GeneratorFeeYearStatisticsInnerServiceSMOImpl.java

@@ -439,7 +439,7 @@ public class GeneratorFeeYearStatisticsInnerServiceSMOImpl implements IGenerator
 
         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;

+ 87 - 14
springboot/src/test/java/com/java110/AppTest.java

@@ -11,6 +11,7 @@ import org.bouncycastle.util.encoders.Base64;
 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 @@ import java.util.Map;
 /**
  * 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 @@ public class AppTest
         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);