众所周知,SimpleDateFormat是线程不安全的,在多线程情况下,格式化时间或解析时间都会遇到意想不到的问题。所以有必要聊聊它的替换方案。
如果qps不高,那就每次都new一个。
我承认这样会浪费一点性能,如果运行100w次,这个耗时可能会比后面几种方式的耗时多一点,但是你扪心自问,这真的重要么?
使用ThreadLocal
public class DateUtils(){
/**
* 安全的时间格式化对象
*/
public static final ThreadLocal<DateFormat> YYYY_MM_DD_HH_MM_SS = ThreadLocal.withInitial(
() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
);
/**
* 字符串转换成日期
*
* @param str
* @return date
*/
public static Date StrToDate(String str) {
Date date = null;
try {
date = YYYY_MM_DD_HH_MM_SS.get().parse(str);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
/**
* 日期转换成字符串
*
* @param date
* @return date
*/
public static String dateToStr(Date date) {
return YYYY_MM_DD_HH_MM_SS.get().format(date);
}
}
使用apache的commons包
pom引入坐标
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.11</version>
</dependency>
代码使用
System.out.println(DateFormatUtils.format(new Date(), "yyyy-MM-dd hh:mm:ss"));
//作用类似于:simpledateformat类中的parse()方法
String[] pattern = new String[] {"yyyy-MM", "yyyyMM", "yyyy/MM",
"yyyyMMdd", "yyyy-MM-dd", "yyyy/MM/dd",
"yyyyMMddHHmmss",
"yyyy-MM-dd HH:mm:ss",
"yyyy/MM/dd HH:mm:ss"};
System.out.println(DateUtils.parseDateStrictly("2023-11-14 22:15:15", pattern));
上面的parseDateStrictly 就是从parsePatterns里面多个格式里找到一个符合给定str格式的pattern来解析成Date。如果找不到合适的pattern就会抛异常。
与parseDateStrictly对应的还有一个叫parseDate的方法,后者的问题是如果找不到合适的parttern不会跑异常,但是会返回一个奇怪的结果。
强烈建议使用parseDateStrictly。
使用LocalDateTime
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String str1 = formatter.format(LocalDateTime.now());
System.out.println(str1);//2021-07-21 07:17:34
//解析:字符串-->日期
LocalDateTime localTime = LocalDateTime.parse("2021-07-21 07:17:34", formatter);
建议使用方案三