在常用的调度平台,都会提供一个{{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'