• 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 final Pattern namePattern = Pattern.compile("(?<format>[yMd\\-]+):?(?<op>\\+|\\-)?(?<num>[0-9]+)?(?<scale>[a-zA-Z])?");
    
        /**
         * 正则查找动态日期字符串'${yyyyMMdd:+7d}',并进行格式化
         * @param sourStr
         * @return
         */
        public static String dynamicFormat(String sourStr) {
            String targetStr = sourStr;
    
            try {
                Matcher 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' 或 'yyyy-MM-dd:+1d'
         * @return 2021-11-23
         * 根据格式串分别匹配出日期格式、加or减、加减数量和尺度
         */
        public static String getDynamicDate(String key) {
            Matcher dateMatcher = namePattern.matcher(key);
            LocalDateTime now = LocalDateTime.now();
            String target=null;
            while (dateMatcher.find()) {
                String format= dateMatcher.group("format");
                String op= dateMatcher.group("op");
                String num= dateMatcher.group("num");
                String scale= dateMatcher.group("scale");
                DateFormatEnum dynamicDate = getDateFormat(format);
                if (op == null) {
                    return dynamicDate.format(now);
                }
    
                DateScaleEnum dateScaleEnum = DateScaleEnum.valueOf(scale);
                LocalDateTime calculate = dateScaleEnum.calculate(now, op, Integer.valueOf(num));
    
                target= dynamicDate.format(calculate);
    
            }
            return target;
        }
    
        /**
         * 根据用户提供的format对日期格式化
         * @param format
         * @return
         */
        public static DateFormatEnum getDateFormat(String format) {
            switch (format) {
                case "yyyy":
                    return DateFormatEnum.Y;
                case "yyyy-MM":
                    return DateFormatEnum.YM;
                case "yyyyMM":
                    return DateFormatEnum.YM3;
                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:-1y}' and dt<='${yyyyMM:+10M}' and dt='${yyyyMMdd}'";
            System.out.println(sql);
            String newSql = dynamicFormat(sql);
            System.out.println(newSql);
    
    
        }
    }

    打印:

    select a,b,c from table where dt>='${yyyy:-1y}' and dt<='${yyyyMM:+10M}' and dt='${yyyyMMdd}'
    select a,b,c from table where dt>='2020' and dt<='202210' and dt='20211201'

     补充用法:如果想写去年一月这样的日期,怎么办?

    其实不需要再把正则表达式进一步优化,现在的方式就可以支持了。

     public static void main(String[] args) {
            String sql="select a,b,c from table " +
                    "where dt>='${yyyy:-1y}-01' and dt<='${yyyyMM:+10M}' and dt='${yyyy-MM-dd} 00:00:00'";
            System.out.println(sql);
            String newSql = dynamicFormat(sql);
            System.out.println(newSql);
        }
    
    /**
    输出:
    select a,b,c from table where dt>='${yyyy:-1y}-01' and dt<='${yyyyMM:+10M}' and dt='${yyyy-MM-dd} 00:00:00'
    select a,b,c from table where dt>='2020-01' and dt<='202210' and dt='2021-12-01 00:00:00'
    */
  • 相关阅读:
    习惯的本质:逐步建立新的常态
    如何度过有用的每一天
    如何利用晚上八点到十点这段时间自我提升
    为什么很多年轻人总会感到迷茫
    当你学会专注,人生才算真正成熟
    如何过上简单的生活
    游标
    触发器

    函数
  • 原文地址:https://www.cnblogs.com/wangbin2188/p/15625636.html
Copyright © 2020-2023  润新知