有序日期时间字符串转Date
package com.strap.common.date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
/**
* 有序日期时间字符串转换器
* 仅支持时间格式按序排列的日期格式转化
* yyyy(yy) -> MM -> dd -> HH -> mm -> ss -> SSS
*/
public class DateParser {
private DateParser() {
}
private static final ConcurrentHashMap<String, SimpleDateFormat> FORMATTER_CACHE = new ConcurrentHashMap<>();
private static SimpleDateFormat getFormatter(String pattern) {
return FORMATTER_CACHE.computeIfAbsent(pattern, SimpleDateFormat::new);
}
private static final String[] VALID_DATE_ARR = new String[]{"yyyy", "MM", "dd", "HH", "mm", "ss", "SSS"};
/**
* 提取数字
*/
private static List<String> loadNumbers(String str) {
if (str == null || str.length() == 0) {
return Collections.emptyList();
}
List<String> numbers = new ArrayList<>();
StringBuilder currentNumber = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (Character.isDigit(ch)) {
currentNumber.append(ch);
} else if (currentNumber.length() > 0) {
numbers.add(currentNumber.toString());
currentNumber.setLength(0);
}
}
if (currentNumber.length() > 0) {
numbers.add(currentNumber.toString());
}
return numbers;
}
/**
* 调整补0
*/
private static String adjust(String n, int length) {
int sub = length - n.length();
if (sub == 0) {
return n;
} else if (sub < 0) {
return n.substring(0, length);
} else {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < sub; i++) {
builder.append('0');
}
builder.append(n);
return builder.toString();
}
}
/**
* 纯数字字符串转日期
*/
private static Date parseSimpleNumber(String dateStr) throws ParseException {
if (dateStr.length() > 3) {
StringBuilder builder = new StringBuilder();
int index = 0;
for (String s : VALID_DATE_ARR) {
int end = index + s.length();
if (end <= dateStr.length()) {
builder.append(s);
index += s.length();
} else {
return parse(dateStr.substring(0, index), builder.toString());
}
}
}
return null;
}
private static Date parseMoreNumbers(List<String> numbers) throws ParseException {
StringBuilder pattern = new StringBuilder();
StringBuilder dateStr = new StringBuilder();
for (int i = 0; i < VALID_DATE_ARR.length; i++) {
if (i < numbers.size()) {
String n = numbers.get(i);
String p = VALID_DATE_ARR[i];
if (n.length() > p.length()) {
numbers.add(i + 1, n.substring(p.length()));
}
if (i == 0) {
// yyyy默认两位年份都拼接20
n = n.length() == 2 ? "20" + n : n;
}
pattern.append(p);
dateStr.append(adjust(n, p.length()));
} else {
break;
}
}
return pattern.length() > 0 ? parse(dateStr.toString(), pattern.toString()) : null;
}
private static Date parse(String dateStr, String pattern) throws ParseException {
SimpleDateFormat formatter = getFormatter(pattern);
synchronized (formatter) {
return formatter.parse(dateStr);
}
}
public static Date parse(String dateStr) {
try {
List<String> numbers = loadNumbers(dateStr);
return numbers.size() == 1 ? parseSimpleNumber(numbers.get(0)) : parseMoreNumbers(numbers);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
测试代码
public static void main(String[] args) throws Exception {
SimpleDateFormat printFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
printTestDate("2016-07-14 19:47:29", printFormat);
printTestDate("16-07-14 19:47:29", printFormat);
printTestDate("2016-07-14T19:47:29.431+08:00", printFormat);
printTestDate("2016年01月14日 19:47:29", printFormat);
printTestDate("2016年1月14日", printFormat);
printTestDate("19年1月14日", printFormat);
printTestDate("2016-07-14 19:47:29", printFormat);
printTestDate("2016年07月14日 19时47分29秒113毫秒", printFormat);
printTestDate("20160714 194729", printFormat);
printTestDate("20160714 19:47:29", printFormat);
printTestDate("20160714194729", printFormat);
printTestDate("201607141947", printFormat);
printTestDate("2016071419", printFormat);
printTestDate("20160714", printFormat);
printTestDate("201607", printFormat);
printTestDate("2016", printFormat);
}
public static void printTestDate(String dateStr, SimpleDateFormat printFormat) throws ParseException {
System.out.println("原始值:" + dateStr + "========转化后:" + printFormat.format(DateParser.parse(dateStr)));
}
运行结果