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])+"=====");
}
}
}
Java 日期时间表达式,${yyyy-MM-dd} 获取当前日期增减n天,n年,不符合表达式的取原值;(正则支持;JDK8;)
最新推荐文章于 2022-11-02 11:00:00 发布