lxw
2023-08-15 160e150009b51a39fa95d9462c3798ba28d51a09
src/main/java/com/whyc/util/DateUtil.java
@@ -76,8 +76,8 @@
     * 根据返回的最后个数据,如果表存在,则查询筛选条件为<=输入的终止时间;不存在则弃用输入的终止时间
     * 返回的非第一最后数据,查询全表
     */
    public static List<Map<String,List<Object>>> getYearListForSubTables(Date startTime,Date endTime) throws ParseException {
        List<Map<String,List<Object>>> result = new LinkedList<>();
    public static Map<String,List<Date>> getYearList(Date startTime,Date endTime) throws ParseException {
        Map<String,List<Date>> result = new LinkedHashMap<>();
        Calendar startTimeC = Calendar.getInstance();
        startTimeC.setTime(startTime);
        int startYear = startTimeC.get(Calendar.YEAR);
@@ -87,8 +87,7 @@
        int endYear = endTimeC.get(Calendar.YEAR);
        int yearSize = endYear - startYear + 1;
        for (int i = startYear; i <= endYear; i++) {
            Map<String,List<Object>> dateMap = new HashMap<>();
            List<Object> dateList = new LinkedList<>();
            List<Date> dateList = new LinkedList<>();
            if(yearSize == 1){ //起止时间没有跨年
                dateList.add(startTime);
                dateList.add(endTime);
@@ -136,8 +135,7 @@
                dateList.add(instance2.getTime());
            }
            dateMap.put(String.valueOf(i),dateList);
            result.add(dateMap);
            result.put(String.valueOf(i),dateList);
        }
        return result;
    }
@@ -180,7 +178,27 @@
        }
        return yearMonthList;
    }
    public static List<List<Date>> getQueryTimeForSubTables(Date startTimeDate,Date endTimeDate) throws ParseException {
    /**
     *  查询使用时,需要处理 默认表查询的问题
     *  示例:
     *  <p>
     * {2020=[Fri Dec 25 14:12:22 CST 2020, Thu Dec 31 23:59:59 CST 2020]}
     * {2021=[Fri Jan 01 00:00:00 CST 2021, Fri Dec 31 23:59:59 CST 2021]}
     * {2022=[Sat Jan 01 00:00:00 CST 2022, Tue Nov 29 09:12:22 CST 2022]}
     * 或
     * {2020=[Fri Dec 25 14:12:22 CST 2020, Thu Dec 31 23:59:59 CST 2020]}
     * {2021=[Fri Jan 01 00:00:00 CST 2021, Fri Dec 31 23:59:59 CST 2021]}
     * {2022=[Sat Jan 01 00:00:00 CST 2022, Thu Dec 29 09:12:22 CST 2022]}
     * {default=[Wed Dec 14 15:27:13 CST 2022, Thu Dec 29 09:12:22 CST 2022]}
     * </p>
     * key为数字,表示年度分表;default为默认表
     * @param startTimeDate 起始时间
     * @param endTimeDate 终止时间
     * @return 需要查询的表及查询时间
     * @throws ParseException
     */
    public static Map<String,List<Date>> getQueryTimeForSubTables(Date startTimeDate,Date endTimeDate) throws ParseException {
        //根据筛选的时间段,查询出符合要求的各分表记录数
        //首先,如果当前时间超过7月,默认表中只有本年度的;如果没超过7月,默认表还存在上一年度的记录
        Calendar instance = Calendar.getInstance();
@@ -193,42 +211,225 @@
        Date beforeYearTime = instance.getTime();
        instance.setTime(endTimeDate);
        int endTimeYear = instance.get(Calendar.YEAR);
        List<List<Date>> monthTime;
        if(nowYear == beforeYear){ //默认表只有本年度的
            monthTime = DateUtil.getMonthTime(startTimeDate, endTimeDate);
        Calendar startTime = Calendar.getInstance();
        startTime.setTime(startTimeDate);
        Map<String,List<Date>> yearTimeMap = DateUtil.getYearList(startTimeDate, endTimeDate);;
        if(nowYear == beforeYear){ //默认表只有本年度的(超过了半年,默认表记录全部只有本年度的,同时会生成了当前年度的分表)
            //如果查询时间范围包含当前年度,则需要查询默认表
            if(startTimeDate.getYear() >= nowYear && endTimeDate.getYear()<= nowYear){
                //表
                //monthTime.add();
            if(startTime.get(Calendar.YEAR) >= nowYear && endTimeYear <= nowYear){
                //开始时间设置年度初始时间
                Calendar defaultTableStartTime = Calendar.getInstance();
                defaultTableStartTime.set(Calendar.YEAR,nowYear);
                defaultTableStartTime.set(Calendar.MONTH,defaultTableStartTime.getActualMinimum(Calendar.MONTH));
                defaultTableStartTime.set(Calendar.DAY_OF_MONTH,defaultTableStartTime.getActualMinimum(Calendar.DAY_OF_MONTH));
                defaultTableStartTime.set(Calendar.HOUR_OF_DAY,defaultTableStartTime.getActualMinimum(Calendar.HOUR_OF_DAY));
                defaultTableStartTime.set(Calendar.MINUTE,defaultTableStartTime.getActualMinimum(Calendar.MINUTE));
                defaultTableStartTime.set(Calendar.SECOND,defaultTableStartTime.getActualMinimum(Calendar.SECOND));
                //终止时间设置为当前时间
                List<Date> defaultDateList = new LinkedList<>();
                defaultDateList.add(defaultTableStartTime.getTime());
                defaultDateList.add(endTimeDate);
                yearTimeMap.put("default",defaultDateList);
            }
        }else{ //默认表中存在上一年度的记录.上一年的最早时间为beforeYearTime
        }else{ //查询时间范围不在当前年度
            //默认表中存在上一年度的记录.上一年的最早时间为beforeYearTime-上一年的年末
            //判断查询时间范围是否包含默认表中上一年度的时间
            if(instance.getTime().compareTo(beforeYearTime)>0){ //查询时间大于默认表中上一年度时间,说明查询记录也包含在默认表中
                //起始时间
                //终止时间
                List<Date> defaultDateList = new LinkedList<>();
                defaultDateList.add(beforeYearTime);
                defaultDateList.add(endTimeDate);
                yearTimeMap.put("default",defaultDateList);
            }
        }
        return yearTimeMap;
    }
    /**
     * 在分表的情况下使用,按年分表,查询需要切割查询使用 时间倒序
     * <p>
     * 根据传入的起止时间,按照年切割成不同时间段
     *
     * @param startTime 2021-01-01 10:00:00
     * @param endTime   2023-05-01 10:10:10
     * @return 示例
     * 使用方法:
     * 根据返回的第一个数据,如果存在表,则查询筛选条件为>=输入的起始时间;不存在则弃用输入的起始时间
     * 根据返回的最后个数据,如果表存在,则查询筛选条件为<=输入的终止时间;不存在则弃用输入的终止时间
     * 返回的非第一最后数据,查询全表
     */
    public static Map<String,List<Date>> getYearListDesc(Date startTime,Date endTime) throws ParseException {
        Map<String,List<Date>> result = new LinkedHashMap<>();
        Calendar startTimeC = Calendar.getInstance();
        startTimeC.setTime(startTime);
        int startYear = startTimeC.get(Calendar.YEAR);
        Calendar endTimeC = Calendar.getInstance();
        endTimeC.setTime(endTime);
        int endYear = endTimeC.get(Calendar.YEAR);
        int yearSize = endYear - startYear + 1;
        for (int i = endYear; i >= startYear; i--) {
            List<Date> dateList = new LinkedList<>();
            if(yearSize == 1){ //起止时间没有跨年
                dateList.add(startTime);
                dateList.add(endTime);
            }
            else if(i==startYear){ //第一年
                dateList.add(startTime);
                Calendar instance = Calendar.getInstance();
                instance.set(Calendar.YEAR,i);
                instance.set(Calendar.MONTH,instance.getActualMaximum(Calendar.MONTH));
                instance.set(Calendar.DAY_OF_MONTH,instance.getActualMaximum(Calendar.DAY_OF_MONTH));
                instance.set(Calendar.HOUR_OF_DAY,instance.getActualMaximum(Calendar.HOUR_OF_DAY));
                instance.set(Calendar.MINUTE,instance.getActualMaximum(Calendar.MINUTE));
                instance.set(Calendar.SECOND,instance.getActualMaximum(Calendar.SECOND));
                dateList.add(instance.getTime());
            }
            else if(i== endYear){ //尾年
                Calendar instance = Calendar.getInstance();
                instance.set(Calendar.YEAR,i);
                instance.set(Calendar.MONTH,instance.getActualMinimum(Calendar.MONTH));
                instance.set(Calendar.DAY_OF_MONTH,instance.getActualMinimum(Calendar.DAY_OF_MONTH));
                instance.set(Calendar.HOUR_OF_DAY,instance.getActualMinimum(Calendar.HOUR_OF_DAY));
                instance.set(Calendar.MINUTE,instance.getActualMinimum(Calendar.MINUTE));
                instance.set(Calendar.SECOND,instance.getActualMinimum(Calendar.SECOND));
                dateList.add(instance.getTime());
                dateList.add(endTime);
            }else{
                Calendar instance = Calendar.getInstance();
                instance.set(Calendar.YEAR,i);
                instance.set(Calendar.MONTH,instance.getActualMinimum(Calendar.MONTH));
                instance.set(Calendar.DAY_OF_MONTH,instance.getActualMinimum(Calendar.DAY_OF_MONTH));
                instance.set(Calendar.HOUR_OF_DAY,instance.getActualMinimum(Calendar.HOUR_OF_DAY));
                instance.set(Calendar.MINUTE,instance.getActualMinimum(Calendar.MINUTE));
                instance.set(Calendar.SECOND,instance.getActualMinimum(Calendar.SECOND));
                dateList.add(instance.getTime());
                Calendar instance2 = Calendar.getInstance();
                instance2.set(Calendar.YEAR,i);
                instance2.set(Calendar.MONTH,instance2.getActualMaximum(Calendar.MONTH));
                instance2.set(Calendar.DAY_OF_MONTH,instance2.getActualMaximum(Calendar.DAY_OF_MONTH));
                instance2.set(Calendar.HOUR_OF_DAY,instance2.getActualMaximum(Calendar.HOUR_OF_DAY));
                instance2.set(Calendar.MINUTE,instance2.getActualMaximum(Calendar.MINUTE));
                instance2.set(Calendar.SECOND,instance2.getActualMaximum(Calendar.SECOND));
                dateList.add(instance2.getTime());
            }
            //如果查询的范围,
            monthTime = DateUtil.getMonthTime(startTimeDate, endTimeDate);
            result.put(String.valueOf(i),dateList);
        }
        return result;
    }
    /**
     *  查询使用时,需要处理 默认表查询的问题 倒序
     *  示例:
     *  <p>
     * {2020=[Fri Dec 25 14:12:22 CST 2020, Thu Dec 31 23:59:59 CST 2020]}
     * {2021=[Fri Jan 01 00:00:00 CST 2021, Fri Dec 31 23:59:59 CST 2021]}
     * {2022=[Sat Jan 01 00:00:00 CST 2022, Tue Nov 29 09:12:22 CST 2022]}
     * 或
     * {2020=[Fri Dec 25 14:12:22 CST 2020, Thu Dec 31 23:59:59 CST 2020]}
     * {2021=[Fri Jan 01 00:00:00 CST 2021, Fri Dec 31 23:59:59 CST 2021]}
     * {2022=[Sat Jan 01 00:00:00 CST 2022, Thu Dec 29 09:12:22 CST 2022]}
     * {default=[Wed Dec 14 15:27:13 CST 2022, Thu Dec 29 09:12:22 CST 2022]}
     * </p>
     * key为数字,表示年度分表;default为默认表
     * @param startTimeDate 起始时间
     * @param endTimeDate 终止时间
     * @return 需要查询的表及查询时间
     * @throws ParseException
     */
    public static Map<String,List<Date>> getQueryTimeForSubTablesDesc(Date startTimeDate,Date endTimeDate) throws ParseException {
        //根据筛选的时间段,查询出符合要求的各分表记录数
        //首先,如果当前时间超过7月,默认表中只有本年度的;如果没超过7月,默认表还存在上一年度的记录
        Calendar now = Calendar.getInstance();
        if(endTimeDate.compareTo(now.getTime())>0){ //校验优化最大查询时间
            endTimeDate = now.getTime();
        }
        Calendar timeBefore7Month = Calendar.getInstance();
        timeBefore7Month.add(Calendar.MONTH,-7);
        LinkedHashMap<String,List<Date>> yearTimeMap = (LinkedHashMap<String, List<Date>>) DateUtil.getYearListDesc(startTimeDate, endTimeDate);
        Map<String,List<Date>> yearTimeDescMap = new LinkedHashMap<>();
        boolean existDefaultYear = false;
        /*if(nowYear == beforeYear){ //默认表只有本年度的(超过了半年,默认表记录全部只有本年度的,同时会生成了当前年度的分表)
            //如果查询时间范围包含当前年度,则需要查询默认表
            if(startTime.get(Calendar.YEAR) >= nowYear && endTimeYear <= nowYear){
                //开始时间设置年度初始时间
                Calendar defaultTableStartTime = Calendar.getInstance();
                defaultTableStartTime.set(Calendar.YEAR,nowYear);
                defaultTableStartTime.set(Calendar.MONTH,defaultTableStartTime.getActualMinimum(Calendar.MONTH));
                defaultTableStartTime.set(Calendar.DAY_OF_MONTH,defaultTableStartTime.getActualMinimum(Calendar.DAY_OF_MONTH));
                defaultTableStartTime.set(Calendar.HOUR_OF_DAY,defaultTableStartTime.getActualMinimum(Calendar.HOUR_OF_DAY));
                defaultTableStartTime.set(Calendar.MINUTE,defaultTableStartTime.getActualMinimum(Calendar.MINUTE));
                defaultTableStartTime.set(Calendar.SECOND,defaultTableStartTime.getActualMinimum(Calendar.SECOND));
                //终止时间设置为当前时间
                List<Date> defaultDateList = new LinkedList<>();
                //defaultDateList.add(defaultTableStartTime.getTime());
                defaultDateList.add(startTimeDate);
                defaultDateList.add(endTimeDate);
                yearTimeMap.put("default",defaultDateList);
                existDefaultYear = true;
            }
        }else{ //查询时间范围不在当前年度
            //默认表中存在上一年度的记录.上一年的最早时间为beforeYearTime-上一年的年末
            //判断查询时间范围是否包含默认表中上一年度的时间
            if(instance.getTime().compareTo(beforeYearTime)>0){ //查询时间大于默认表中上一年度时间,说明查询记录也包含在默认表中
                //起始时间
                //终止时间
                List<Date> defaultDateList = new LinkedList<>();
                defaultDateList.add(startTimeDate);
                defaultDateList.add(endTimeDate);
                yearTimeMap.put("default",defaultDateList);
                existDefaultYear = true;
            }
        }*/
        if(startTimeDate.before(now.getTime()) || endTimeDate.after(timeBefore7Month.getTime())){
            List<Date> defaultDateList = new LinkedList<>();
            defaultDateList.add(startTimeDate);
            defaultDateList.add(endTimeDate);
            yearTimeMap.put("default",defaultDateList);
            existDefaultYear = true;
        }
        //调整下顺序,将default调整到首位
        if(existDefaultYear){
            List<Date> defaultTimeList = yearTimeMap.get("default");
            yearTimeDescMap.put("default",defaultTimeList);
        }
        Set<String> yearSet = yearTimeMap.keySet();
        for (String year : yearSet) {
            if(!year.equals("default")){
                yearTimeDescMap.put(year,yearTimeMap.get(year));
            }
        }
        return null;
        return yearTimeDescMap;
    }
    public static void main(String[] args) throws ParseException {
        Date d1 = YYYY_MM_DD_HH_MM_SS.parse("2022-12-25 14:12:22");
        Date d1 = YYYY_MM_DD_HH_MM_SS.parse("2020-12-25 14:12:22");
        Date d2 = YYYY_MM_DD_HH_MM_SS.parse("2022-12-29 09:12:22");
        List<Map<String, List<Object>>> yearListForSubTables = getYearListForSubTables(d1, d2);
        for (int i = 0; i < yearListForSubTables.size(); i++) {
            Map<String, List<Object>> stringListMap = yearListForSubTables.get(i);
            System.out.println(stringListMap);
        Map<String, List<Date>> yearListForSubTables = getQueryTimeForSubTablesDesc(d1, d2);
        Set<String> strings = yearListForSubTables.keySet();
        Set<Map.Entry<String, List<Date>>> entries = yearListForSubTables.entrySet();
        for (Map.Entry<String, List<Date>> entry : entries) {
            System.out.println(entry);
        }
        /*String dateStr = "2023-07-01 00:00:01";
        Date date = YYYY_MM_DD_HH_MM_SS.parse(dateStr);
        Calendar instance = Calendar.getInstance();
        instance.setTime(date);
        instance.add(Calendar.MONTH,-6);
        System.out.println(YYYY_MM_DD_HH_MM_SS.format(instance.getTime()));*/
    }
}