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])+"=====");
        }
    }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值