zoukankan      html  css  js  c++  java
  • 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'
    */
  • 相关阅读:
    phpcms后台进入地址(包含No permission resources错误)
    phpmyadmin上传大sql文件办法
    ubuntu彻底卸载mysql
    Hdoj 2602.Bone Collector 题解
    一篇看懂词向量
    Hdoj 1905.Pseudoprime numbers 题解
    The Python Challenge 谜题全解(持续更新)
    Hdoj 2289.Cup 题解
    Hdoj 2899.Strange fuction 题解
    Hdoj 2199.Can you solve this equation? 题解
  • 原文地址:https://www.cnblogs.com/wangbin2188/p/15625636.html
Copyright © 2011-2022 走看看