package com.ruoyi.errand.utils; import cn.hutool.core.date.DateUtil; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.ZoneId; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.List; public class PaymentCycleHelper { // 格式化日期为 "yyyy-MM" private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM"); // 根据 25% 首付款支付时间计算首笔付款周期 public static String getFirstPaymentCycle(Date firstPaymentDate) { Calendar calendar = Calendar.getInstance(); calendar.setTime(firstPaymentDate); int month = calendar.get(Calendar.MONTH) + 1; // 获取月份(1-12) if (month >= 10 && month <= 12) { // 10月-12月,首笔付款周期为次年1月 calendar.add(Calendar.YEAR, 1); calendar.set(Calendar.MONTH, Calendar.JANUARY); // 设置为1月 } else if (month >= 1 && month <= 3) { // 1月-3月,首笔付款周期为当年4月 calendar.set(Calendar.MONTH, Calendar.APRIL); } else if (month >= 4 && month <= 6) { // 4月-6月,首笔付款周期为当年7月 calendar.set(Calendar.MONTH, Calendar.JULY); } else if (month >= 7 && month <= 9) { // 7月-9月,首笔付款周期为当年10月 calendar.set(Calendar.MONTH, Calendar.OCTOBER); } // 返回首笔付款周期格式 "yyyy-MM" return sdf.format(calendar.getTime()); } public static String getCurrentQuarter(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); int year = calendar.get(Calendar.YEAR); int month = calendar.get(Calendar.MONTH) + 1; // 获取月份(1-12) // 计算当前季度的起始月份 int quarterStartMonth = ((month - 1) / 3) * 3 + 1; return String.format("%d-%02d", year, quarterStartMonth); } /** * 获取季度信息 * @param date * @param offset * @return */ public static String getQuarterByOffset(Date date, int offset) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); int year = calendar.get(Calendar.YEAR); int month = calendar.get(Calendar.MONTH) + 1; // Java中月份是从0开始的 // 当前季度索引:0(Q1),1(Q2),2(Q3),3(Q4) int currentQuarter = (month - 1) / 3; // 计算目标季度的索引 int targetQuarter = currentQuarter + offset; // 处理跨年情况 year += targetQuarter / 4; targetQuarter = (targetQuarter % 4 + 4) % 4; // 保证结果在0~3之间 // 获取目标季度的起始月份 int quarterStartMonth = targetQuarter * 3 + 1; return String.format("%d-%02d", year, quarterStartMonth); } // 根据首笔付款日期往后推 20 期,计算分期支付周期 public static String getQuarterlyPaymentCycles(Date firstPaymentDate) { Calendar calendar = Calendar.getInstance(); calendar.setTime(firstPaymentDate); // 获取首笔付款周期 String firstPaymentCycle = getFirstPaymentCycle(firstPaymentDate); try { calendar.setTime(sdf.parse(firstPaymentCycle)); // 将首笔付款周期解析为日期 } catch (Exception e) { e.printStackTrace(); return ""; } // 往后推 20 期,每期为3个月 String[] paymentCycles = new String[20]; for (int i = 0; i < 20; i++) { paymentCycles[i] = sdf.format(calendar.getTime()); calendar.add(Calendar.MONTH, 3); // 每次增加 3 个月 } return String.join(",", Arrays.asList(paymentCycles)); } // 根据当前季度首笔付款日期往后推 20 期,计算分期支付周期 public static List getQuarterlyPaymentCyclesList(Date firstPaymentDate) { Calendar calendar = Calendar.getInstance(); calendar.setTime(firstPaymentDate); // 获取首笔付款周期 String firstPaymentCycle = getCurrentQuarter(firstPaymentDate); try { calendar.setTime(sdf.parse(firstPaymentCycle)); // 将首笔付款周期解析为日期 } catch (Exception e) { e.printStackTrace(); return null; } // 往后推 20 期,每期为3个月 String[] paymentCycles = new String[20]; for (int i = 0; i < 20; i++) { paymentCycles[i] = sdf.format(calendar.getTime()); calendar.add(Calendar.MONTH, 3); // 每次增加 3 个月 } return Arrays.asList(paymentCycles); } // 根据首笔付款日期往后推 4 期,计算分期支付周期 public static List getQuarterlyPaymentCyclesFour(Date firstPaymentDate) { Calendar calendar = Calendar.getInstance(); calendar.setTime(firstPaymentDate); // 获取首笔付款周期 String firstPaymentCycle = getFirstPaymentCycle(firstPaymentDate); try { calendar.setTime(sdf.parse(firstPaymentCycle)); // 将首笔付款周期解析为日期 } catch (Exception e) { e.printStackTrace(); return null; } // 往后推 20 期,每期为3个月 String[] paymentCycles = new String[4]; for (int i = 0; i < 4; i++) { paymentCycles[i] = sdf.format(calendar.getTime()); calendar.add(Calendar.MONTH, 3); // 每次增加 3 个月 } return Arrays.asList(paymentCycles); } /** * 计算 25% 首付款支付时间属于 20 期中的第几期 * * @param firstPaymentDate 25% 首付款支付时间(Date 类型) * @return 期数(1~20),超出则返回 -1 */ public static int getPaymentPeriod(Date firstPaymentDate) { //判断时间超过5年,则直接返回20 long month = DateUtil.betweenMonth(new Date(),firstPaymentDate,true); if(month >= 60){ return 20; } List times = getQuarterlyPaymentCyclesList(firstPaymentDate); //获取当前日期季度 String current = getCurrentQuarter(new Date()); // 计算当前属于哪一期 for (int i = 0; i <= times.size(); i++) { String itemTime = times.get(i); if (itemTime.equals(current)) { return i; } } // 如果当前日期超出 20 期,则返回 -1 return 0; } /** * 将 Date 转换为 LocalDate * * @param date Date 类型的日期 * @return LocalDate 类型的日期 */ private static LocalDate convertToLocalDate(Date date) { return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); } public static void main(String[] args) { System.out.println(getPaymentPeriod(DateUtil.parseDate(" 2023-10-03")));; } }