想必大家对SimpleDateFormat并不陌生。SimpleDateFormat 是 Java 中一个非常常用的类,该类用来对日期字符串进行解析和格式化输出,但如果使用不小心会导致非常微妙和难以调试的问题,因为 DateFormat 和 SimpleDateFormat 类不都是线程安全的,在多线程环境下调用 format() 和 parse() 方法应该使用同步代码或者ThreadLocal来避免问题。 本工具类采用第二种方式实现线程安全,仅供参考,如有误,联系指出改正
package com.qyw.test;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author qyw
* @description jdk 1.8以下线程安全的日期格式化工具,1.8请使用java.time API
* @date Created in 10:07 2018/12/4
*/
public class DateUtils {
// Suppresses default constructor, ensuring non-instantiability.
private DateUtils() {
throw new RuntimeException("工具类不允许实例化");
}
// 默认初始化此格式的格式化器
private static final String DEFAULT_PATTERN="yyyy-MM-dd";
private static final ThreadLocal<Map<String,DateFormat>> dataFormatMap = new ThreadLocal<Map<String,DateFormat>>() {
@Override
protected Map<String, DateFormat> initialValue() {
final SimpleDateFormat sf = new SimpleDateFormat(DEFAULT_PATTERN);
final HashMap<String, DateFormat> initMap = new HashMap<String, DateFormat>();
initMap.put(DEFAULT_PATTERN,sf);
return initMap;
}
};
private static DateFormat getDateFormat(final String pattern){
final Map<String, DateFormat> map = dataFormatMap.get();
DateFormat dateFormat = map.get(pattern);
if(dateFormat == null){
dateFormat = new SimpleDateFormat(pattern);
map.put(pattern,dateFormat);
}
return dateFormat;
}
/**
* @author qyw
* @description 校验字符串是否为指定的日期格式,含逻辑严格校验,2007/02/30返回false
* @date Created in 21:06 2019/1/31
**/
public static boolean isValidDate(String dateString) {
boolean convertSuccess = true;
// 指定日期格式为四位年/两位月份/两位日期,注意yyyy-MM-dd区分大小写;
final DateFormat dateFormat = getDateFormat("yyyy-MM-dd");
try {
// 设置lenient为false.
// 否则SimpleDateFormat会比较宽松地验证日期,比如2007/02/29会被接受,并转换成2007/03/01
dateFormat.setLenient(false);
dateFormat.parse(dateString);
} catch (ParseException e) {
convertSuccess = false;
}
return convertSuccess;
}
/**
* @author qyw
* @description 按指定格式格式化日期
* @date Created in 10:25 2018/12/4
* @param [date, pattern]
* @return java.lang.String
**/
public static String format(Date date,String pattern){
return getDateFormat(pattern).format(date);
}
/**
* @author qyw
* @description 按指定格式解析日期
* @date Created in 10:25 2018/12/4
* @param [date, pattern]
* @return java.util.Date
**/
public static Date parse(String date,String pattern) throws ParseException {
return getDateFormat(pattern).parse(date);
}
}