前言
这个代码是我负责的项目拿出来的,这个方法是框架里的一个基础类里的方法。主要作用是:把字符串转成日期。
重构前代码
public static java.util.Date formatDate(String strValue) throws ParseException {
Pattern pattern1 = Pattern.compile("^\\d{4}-\\d{2}-\\d{2}\\s+\\d{2}:\\d{2}:\\d{2}");
Pattern pattern2 = Pattern.compile("^\\d{4}\\d{2}\\d{2}\\s+\\d{2}\\d{2}\\d{2}");
Pattern pattern3 = Pattern.compile("^\\d{4}-\\d{2}-\\d{2}");
Pattern pattern4 = Pattern.compile("^\\d{4}\\d{2}\\d{2}");
Pattern pattern41 = Pattern.compile("^\\d{4}-\\d{1}-\\d{1}");
Pattern pattern42 = Pattern.compile("^\\d{4}-\\d{1}-\\d{2}");
Pattern pattern43 = Pattern.compile("^\\d{4}-\\d{2}-\\d{1}");
Pattern pattern5 = Pattern.compile("^\\d{4}");
Pattern pattern6 = Pattern.compile("^\\d{4}/\\d{2}/\\d{2}");
Pattern pattern7 = Pattern.compile("^\\d{4}年\\d{2}月\\d{2}日");
Pattern pattern8 = Pattern.compile("^\\d{4}年\\d{1}月\\d{1}日");
Pattern pattern9 = Pattern.compile("^\\d{4}年\\d{1}月\\d{2}日");
Pattern pattern10 = Pattern.compile("^\\d{4}年\\d{2}月\\d{1}日");
Matcher matcher1 = pattern1.matcher(strValue);
Matcher matcher2 = pattern2.matcher(strValue);
Matcher matcher3 = pattern3.matcher(strValue);
Matcher matcher4 = pattern4.matcher(strValue);
Matcher matcher5 = pattern5.matcher(strValue);
try {
SimpleDateFormat datePaser;
if (matcher1.matches()) {
datePaser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return datePaser.parse(strValue);
}
if (matcher2.matches()) {
datePaser = new SimpleDateFormat("yyyyMMdd HHmmss");
return datePaser.parse(strValue);
}
if (matcher3.matches()) {
datePaser = new SimpleDateFormat("yyyy-MM-dd");
return datePaser.parse(strValue);
}
if (matcher4.matches()) {
datePaser = new SimpleDateFormat("yyyyMMdd");
return datePaser.parse(strValue);
}
if (pattern41.matcher(strValue).matches()) {
datePaser = new SimpleDateFormat("yyyy-M-d");
return datePaser.parse(strValue);
}
if (pattern42.matcher(strValue).matches()) {
datePaser = new SimpleDateFormat("yyyy-M-dd");
return datePaser.parse(strValue);
}
if (pattern42.matcher(strValue).matches()) {
datePaser = new SimpleDateFormat("yyyy-MM-d");
return datePaser.parse(strValue);
}
if (matcher5.matches()) {
datePaser = new SimpleDateFormat("yyyy");
return datePaser.parse(strValue);
}
if (pattern43.matcher(strValue).matches()) {
datePaser = new SimpleDateFormat("yyyy-M-dd");
return datePaser.parse(strValue);
}
if (pattern6.matcher(strValue).matches()) {
datePaser = new SimpleDateFormat("yyyy/MM/dd");
return datePaser.parse(strValue);
}
if (pattern7.matcher(strValue).matches()) {
datePaser = new SimpleDateFormat("yyyy年MM月dd日");
return datePaser.parse(strValue);
}
if (pattern8.matcher(strValue).matches()) {
datePaser = new SimpleDateFormat("yyyy年M月d日");
return datePaser.parse(strValue);
}
if (pattern9.matcher(strValue).matches()) {
datePaser = new SimpleDateFormat("yyyy年M月dd日");
return datePaser.parse(strValue);
}
if (pattern10.matcher(strValue).matches()) {
datePaser = new SimpleDateFormat("yyyy年MM月d日");
return datePaser.parse(strValue);
}
throw new ParseException(strValue + "不符合date转换格式", 0);
} catch (ParseException e1) {
throw new ParseException(strValue + "date转换异常", 0);
}
}
代码的问题
1:变量多,变量命名不规范。
2:变量的定义与使用间隔太远,可读性不好。
3:书写规范不统一,一个方法保留了多种风格。
4:正则校验顺序问题,使用的正则是非闭合的(有开始符,没有结束符)。
5:代码重复。
6:去掉不合理的代码,比如"yyyy"的转换。感觉乱传都可以转成日期,留下祸根。。。
改良版
/**
* 字符串转成util.Date
* 支持字符串格式:yyy-MM-dd HH:mm:ss,yyyyMMdd HHmmss,yyyy-MM-dd,yyyyMMdd,yyyy,yyyy/MM/dd,yyyy年MM月dd日,yyyy年M月d日,yyyy年M月dd日,yyyy年MM月d日
*/
public static java.util.Date formatDate(String strValue) throws ParseException {
Map<String,String> mRgx = getFixMap();
for ( Map.Entry<String,String> entry : mRgx.entrySet()) {
if (Pattern.compile(entry.getValue()).matcher(strValue).matches()) {
return new SimpleDateFormat(entry.getKey()).parse(strValue);
}
}
throw new ParseException(strValue + "不符合date转换格式", 0);
}
private static Map<String,String> fixMap;
private static Map getFixMap() {
if (fixMap == null) {
fixMap = new HashMap();
fixMap.put("yyyy-MM-dd HH:mm:ss", "^\\d{4}-\\d{2}-\\d{2}\\s+\\d{2}:\\d{2}:\\d{2}$");
fixMap.put("yyyy-MM-dd", "^\\d{4}-\\d{1,2}-\\d{1,2}$");
fixMap.put("yyyyMMdd", "^\\d{4}\\d{2}\\d{2}$");
fixMap.put("yyyy/MM/dd", "^\\d{4}/\\d{1,2}/\\d{1,2}$");
fixMap.put("yyyy年MM月dd日", "^\\d{4}年\\d{1,2}月\\d{1,2}日$");
}
return fixMap;
}
PS
1:去掉一些永远用不上的,或者根本不能用的,比如"yyyy",自由跟自毁一线之差。
2:合并一些可以合并的,比如正则表达式 “^\d{4}-\d{1}-\d{1}” 、 “^\d{4}-\d{1}-\d{2}” 、 “^\d{4}-\d{2}-\d{1}” 、 “^\d{4}-\d{2}-\d{2}” 。可以合并成 “^\d{4}-\d{1,2}-\d{1,2}”
3:另外要扩展方便(虽然也没什么好扩展的),引入了Map. 。
4:增加正则表达式结束符,严谨匹配。