Java 日期時間表達式,${yyyy-MM-dd} 獲取當前日期增減n天,n年,不符合表達式的取原值;(正則支持;JDK8;)

public class Test {
    /**
     * 分區字段值日期表達式:格式:${yyyyMMdd HH:mm:ss;+1;y},支持年月日時,其中兩個分號必須有
     */
    private static final String PARTITION_DATE_EX =
            "^(\\$\\{((yyyy([-/.年]{0,1}MM([-/.月]{0,1}dd日{0,1}){0,1}){0,1})\\s*(HH(:{0,1}mm(:{0,1}ss){0,1}){0,1}){0,1});((\\+|-)\\d+){0,1};([YyMmDdHh]){0,1}\\})$";

    /**
     * 分區字段值日期表達式:格式:${yyyyMMdd HH};+1,支持年月日時,其中兩個分號必須有
     */
    public static final String PARTITION_DATE_EX1 =
            "^(\\$\\{((y{0,4}[-/.年]{0,1}M{0,2}[-/.月]{0,1}d{0,2}日{0,1})\\s*H{0,2})\\}(;((\\+|-)\\d+){0,1}){0,1})$";

    /** 分區字段值日期表達式
     *  分區值支持時間表達式,格式:${expression;±數值;單位},實際結果爲 當前時間 ± ( n * 時間單位)
     * expression:yyyyMMdd HH:mm:ss,日期範圍最大到年(yyyy),最小到秒(yyyyMMdd HH:mm:ss),其中日期部分的格式支持:yyyy-MM-dd、yyyy.MM.dd、yyyy/MM/dd、yyyyMMdd、yyyy年MM月dd日
     * 數值:+n,-n 或空字符串
     * 單位:YMDH選擇其一,分別代表年、月、日、時,不區分大小寫,默認單位爲日
     * 注意:兩個分號必傳
     * */
    private static String transDateExpression(String value){
        String valueTemp = value.replaceAll("\\s","");
        if(!Pattern.matches(PARTITION_DATE_EX,valueTemp)){
            return value;
        }
        // 日期格式,在原表達式中截取
        String dateFormat = value.substring(2,value.indexOf(";"));
        // 日期加減數
        String dateValue = valueTemp.substring(valueTemp.indexOf(';')+1,valueTemp.lastIndexOf(';'));
        // 日期加減的單位 Y M D H
        String dateType = valueTemp.substring(valueTemp.lastIndexOf(';')+1,valueTemp.length()-1);

        LocalDateTime currentTime = LocalDateTime.now();
        if(StringUtils.isBlank(dateValue)){
            log.info("根據時間表達式 {} 獲取到的字段值 {}",value, formatDateTime(currentTime,dateFormat));
            return formatDateTime(currentTime,dateFormat);
        }
        LocalDateTime dateTimeValue;
        switch (dateType.toUpperCase()){
            case "Y":
                dateTimeValue = currentTime.plus(Integer.valueOf(dateValue), ChronoUnit.YEARS);
                break;
            case "M":
                dateTimeValue = currentTime.plus(Integer.valueOf(dateValue), ChronoUnit.MONTHS);
                break;
            case "H":
                dateTimeValue = currentTime.plus(Integer.valueOf(dateValue), ChronoUnit.HOURS);
                break;
            default:
                // 默認單位:天
                dateTimeValue = currentTime.plus(Integer.valueOf(dateValue), ChronoUnit.DAYS);
                break;
        }
        log.info("根據時間表達式 {} 獲取到的字段值 {}",value,formatDateTime(dateTimeValue,dateFormat));
        return formatDateTime(dateTimeValue,dateFormat);
    }


    /** 分區字段值日期表達式
     *  1.格式如:${yyyyMMdd HH};+1,視作日期時間表達式
     *  2.表達式支持${yyyy-MM-dd HH}及其中某個或者多個部分按順序組合如${yyyy},${MMdd},${yyyyHH},${yMdH},${MM},${HH};+1等
     *  3.時間單位默認爲表達式的最後一位
     *  4.解析失敗或表達式部分爲空時(${}),當做普通字符串
     * */
    private static String transDateExpression2(String value){
        String valueTemp = value.replaceAll("\\s", "");
        try {
            if (!Pattern.matches(PARTITION_DATE_EX1, valueTemp)) {
                return value;
            }
            // 日期格式,在原表達式中截取
            String dateFormat = value.substring(2, value.indexOf("}"));
            // 日期格式爲空時,直接返回
            if (StringUtils.isBlank(dateFormat)) {
                return value;
            }
            // 日期加減數
            String dateValue = "";
            if (value.contains(";")) {
                dateValue = valueTemp.substring(valueTemp.indexOf(';') + 1);
            }
            // 日期加減的單位 Y M D H
            String dateType = valueTemp.substring(valueTemp.lastIndexOf('}') - 1, valueTemp.lastIndexOf('}'));

            LocalDateTime currentTime = LocalDateTime.now();
            if (StringUtils.isBlank(dateValue)) {
                log.info("根據時間表達式 {} 獲取到的字段值 {}", value, formatDateTime(currentTime, dateFormat));
                return formatDateTime(currentTime, dateFormat);
            }
            LocalDateTime dateTimeValue;
            switch (dateType.toUpperCase()) {
                case "Y":
                    dateTimeValue = currentTime.plus(Integer.valueOf(dateValue), ChronoUnit.YEARS);
                    break;
                case "M":
                    dateTimeValue = currentTime.plus(Integer.valueOf(dateValue), ChronoUnit.MONTHS);
                    break;
                case "D":
                    dateTimeValue = currentTime.plus(Integer.valueOf(dateValue), ChronoUnit.DAYS);
                    break;
                case "H":
                    dateTimeValue = currentTime.plus(Integer.valueOf(dateValue), ChronoUnit.HOURS);
                    break;
                default:
                    return value;
            }
            log.info("根據時間表達式 {} 獲取到的字段值 {}", value, TimeUtil.formatDateTime(dateTimeValue, dateFormat));
            return formatDateTime(dateTimeValue, dateFormat);
        } catch (Exception e) {
            log.warn("解析失敗,輸入的分區表達式作爲普通字符串,expression={},cause = {}", value, e);
            return value;
        }
    }




    /** LocalDateTime 日期時間格式化*/
    private static String formatDateTime(LocalDateTime currDate, String format){
        String res = "-";
        if (currDate == null) {
            return res;
        }
        try {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
            return currDate.format(formatter);
        } catch (Exception e) {
            log.error(e.getMessage());
            return res;
        }
    }

    public static void main(String[] args) {
        String str =
                "${yyyyMMHH};-7,${yyyy},${yyy},${yy};+1,${y};+5,${MM},${MM};+10,${H},${HH};-2,${ddHH},${yyyMdH},${yyMdH},${y-M-d H},${yy-M-d H},${},${  },${yyyyMMdd  };+1,${};+1";
        String[] strs = str.split(",");
        for (int i = 0; i < strs.length; i++) {
            System.out.println(transDateExpression2(strs[i])+"=====");
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章