java实现动态日期格式化

在常用的调度平台,都会提供一个{{ds}}或者${yyyyMMdd}类似的宏变量。

那么这个是怎么实现的呢;

首先定义一个日期加减运算的枚举类,我们可以根据用户提供表达式在当前日期上进行加减运算

public enum DateScaleEnum {
    y {
        @Override
        public LocalDateTime calculate(LocalDateTime origin, String op, Integer num) {
            if (op.equals("+")) {
                return origin.plusYears(num);
            } else {
                return origin.minusYears(num);
            }
        }
    },
    M {
        @Override
        public LocalDateTime calculate(LocalDateTime origin, String op, Integer num) {
            if (op.equals("+")) {
                return origin.plusMonths(num);
            } else {
                return origin.minusMonths(num);
            }
        }
    },
    d {
        @Override
        public LocalDateTime calculate(LocalDateTime origin, String op, Integer num) {
            if (op.equals("+")) {
                return origin.plusDays(num);
            } else {
                return origin.minusDays(num);
            }
        }
    };

    public abstract LocalDateTime calculate(LocalDateTime origin, String op, Integer num);
}

核心类

public class DateFormatUtil {
    private static final Pattern dynamicPattern = Pattern.compile("\\$\\{(.*?)\\}");
    private static Matcher dynamicMatcher;

    private static final Pattern datePattern = Pattern.compile("([yMd\\-]+)(\\+|\\-)([0-9])([a-zA-Z])");
    private static Matcher dateMatcher;

    /**
     * 正则查找动态日期字符串'${yyyyMMdd+7d}',并进行格式化
     * @param sourStr
     * @return
     */
    public static String dynamicFormat(String sourStr) {
        String targetStr = sourStr;

        try {
            dynamicMatcher = dynamicPattern.matcher(targetStr);
            while (dynamicMatcher.find()) {
                String key = dynamicMatcher.group();
                String keyclone = key.substring(2,key.length()-1);
                String value = getDynamicDate(keyclone);
                if (value != null)
                    targetStr = targetStr.replace(key, value);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return targetStr;
    }

    /**
     * 根据日期格式返回日期字符串
     * @param key 'yyyyMMdd+7d'
     * @return 2021-11-23
     * 根据格式串分别匹配出日期格式、加or减、加减数量和尺度
     */
    public static String getDynamicDate(String key) {
        dateMatcher = datePattern.matcher(key);
        LocalDateTime now = LocalDateTime.now();
        String target=null;
        while (dateMatcher.find()) {
            String format=dateMatcher.group(1);
            String op=dateMatcher.group(2);
            String num=dateMatcher.group(3);
            String scale=dateMatcher.group(4);

            DateScaleEnum dateScaleEnum = DateScaleEnum.valueOf(scale);
            LocalDateTime calculate = dateScaleEnum.calculate(now, op, Integer.valueOf(num));
            DateFormatEnum dynamicDate = getDateFormat(format);
            target= dynamicDate.format(calculate);

        }
        return target;
    }

    /**
     * 根据用户提供的format对日期格式化
     * @param format
     * @return
     */
    public static DateFormatEnum getDateFormat(String format) {
        switch (format) {
            case "yyyy":
                return DateFormatEnum.Y;
            case "yyyyMM":
                return DateFormatEnum.YM3;
            case "yyyy-MM":
                return DateFormatEnum.YM;
            case "yyyyMMdd":
                return DateFormatEnum.YMD3;
            case "yyyy-MM-dd":
            default:
                return  DateFormatEnum.YMD;
        }
    }

    public static void main(String[] args) {
        String sql="select a,b,c from table " +
                "where dt>='${yyyy-MM-dd-1d}' and dt<='${yyyy-MM-dd+1d}'";
        System.out.println(sql);
        String newSql = dynamicFormat(sql);
        System.out.println(newSql);

    }
}

打印:

select a,b,c from table where dt>='${yyyy-MM-dd-1d}' and dt<='${yyyy-MM-dd+1d}'
select a,b,c from table where dt>='2021-11-29' and dt<='2021-12-01'

 

上一篇:LocalDateTime


下一篇:java8 LocalDateTime