最近遇到一个需求是excel表格里有日期一栏,但是呢日期的格式是不一定的,产品希望可以将所有格式的日期都可以读取,并保存成同一种格式录入到数据库里。
首先想到的解决方法是使用正则表达式去做匹配,写着写着就越写越多,就想放弃了(而且正则表达式本身规则复杂,不好写),再考虑到正则本身性能比较差,就放弃了这个方法。我觉得这个场景应该是比较常见的,就搜索了下是否有大神有好的解决方式,查询了半天,都没找到有这样的介绍,当然在我不辞辛劳的搜索下,还是在某个犄角旮旯中找到了有大神的提供的解决方式。下面是代码:
private static final String[] DATE_PATTERN_ARRAY = {
defaultDatePattern,
"yyyy/MM/dd",
"yyyy-MM-dd",
"yyyy.MM.dd",
"yyyy/MM/d",
"yyyy/M/dd",
"yyyy/M/d",
"yyyy年MM月dd日"
};
private static String mergePattern = "";
/**
* 使用多种pattern尝试解析日期
*
* @param inputDate inputDate
* @return Date
*/
public static LocalDate commonParse(String inputDate) {
if (StringUtils.isBlank(inputDate)) {
return null;
}
if (StringUtils.isBlank(mergePattern)) {
mergePattern = Arrays.stream(DATE_PATTERN_ARRAY).map(val -> "[" + val + "]").collect(Collectors.joining());
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(mergePattern);
try {
return LocalDate.parse(inputDate, formatter);
} catch (Exception e) {
log.error("parse error", e);
}
return null;
}
复制代码
测试用例:
@Test
public void testCommonParse() {
String[] dateArray = new String[]{
"2021/01/01",
"20210101",
"2021-01-01",
"2021.01.01",
"2021/01/1",
"2021/1/01",
"2021/1/1",
"2021年01月01日"};
for (String date : dateArray) {
LocalDate result = DateFormatUtils.commonParse(date);
Assert.assertNotNull(result);
System.out.println(result);
}
}
复制代码
输出:
2021-01-01
2021-01-01
2021-01-01
2021-01-01
2021-01-01
2021-01-01
2021-01-01
2021-01-01
复制代码
在我自己电脑测试了下,平均耗时在160ms左右,还是挺长的。说明这种多格式解析逻辑还是挺复杂的,在非迫不得己的情况下,还是不推荐大家使用。
顺便记录下如果要解析date的话,可以使用这个工具类:org.apache.commons:commons-lang,类名:org.apache.commons.lang.time.DateUtils
/**
* <p>Parses a string representing a date by trying a variety of different parsers.</p>
*
* <p>The parse will try each parse pattern in turn.
* A parse is only deemed successful if it parses the whole of the input string.
* If no parse patterns match, a ParseException is thrown.</p>
* The parser will be lenient toward the parsed date.
*
* @param str the date to parse, not null
* @param parsePatterns the date format patterns to use, see SimpleDateFormat, not null
* @return the parsed date
* @throws IllegalArgumentException if the date string or pattern array is null
* @throws ParseException if none of the date patterns were suitable (or there were none)
*/
public static Date parseDate(String str, String[] parsePatterns) throws ParseException {
return parseDateWithLeniency(str, parsePatterns, true);
}
复制代码