一、SimpleDateFormat概述
SimpleDateFormat是Java提供的日期格式化类,它可以将日期格式化为指定的字符串,也可以将字符串解析为日期对象。
SimpleDateFormat类中提供了一些预定义的格式,如“yyyy-MM-dd HH:mm:ss”、“yyyy年MM月dd日”等,还可以自定义格式。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String format = sdf.format(new Date());
System.out.println(format);
二、SimpleDateFormat代码示例1:将日期格式化为“YYYYMMDD”格式
通过SimpleDateFormat类,我们可以很容易地实现将日期格式化为YYYYMMDD格式的字符串。
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
String format = sdf.format(new Date());
System.out.println(format);
上面的代码中,定义了一个SimpleDateFormat对象,将其格式化字符串设置为“yyyyMMdd”,即YYYYMMDD格式,然后将当前日期格式化成此格式的字符串。
三、SimpleDateFormat代码示例2:将字符串解析为日期对象
除了将日期格式化为指定字符串,SimpleDateFormat也可以将指定格式的字符串解析成日期对象。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String dateStr = "2022-01-21";
Date date = sdf.parse(dateStr);
System.out.println(date);
上面的代码中,定义了一个SimpleDateFormat对象,将其格式化字符串设置为“yyyy-MM-dd”,然后将日期字符串“2022-01-21”解析成日期对象。
四、SimpleDateFormat的线程安全
SimpleDateFormat是线程不安全的类,如果多个线程同时访问一个SimpleDateFormat实例会引发线程安全问题,通常的做法是为每个线程创建一个SimpleDateFormat实例。
下面是线程不安全的代码示例:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 100000; i++) {
executorService.submit(() -> {
String format = sdf.format(new Date());
System.out.println(format);
});
}
executorService.shutdown();
上面的代码中,定义了一个SimpleDateFormat实例,然后启动10个线程并发调用此实例的format方法,会引发线程安全问题。
下面是线程安全的代码示例:
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 100000; i++) {
executorService.submit(() -> {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String format = sdf.format(new Date());
System.out.println(format);
});
}
executorService.shutdown();
上面的代码中,每个线程都创建了一个SimpleDateFormat对象,避免了线程安全问题。
五、SimpleDateFormat的性能优化
由于SimpleDateFormat是非常常用的日期格式化类,而且线程不安全,所以必须做好性能优化。
首先,可以使用ThreadLocal为每个线程创建一个SimpleDateFormat对象,避免多个线程竞争同一个SimpleDateFormat实例。
public final static ThreadLocal
SDF = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
public static String formatDate(Date date) {
SimpleDateFormat sdf = SFD.get();
return sdf.format(date);
}
其次,可以将日期格式化字符串预编译,避免每次使用都需要解析格式化字符串,提高性能。
public class DateFormatUtil {
private static ConcurrentHashMap<String, SimpleDateFormat> sdfMap = new ConcurrentHashMap<>();
public static String formatDate(Date date, String pattern) {
SimpleDateFormat sdf = sdfMap.getOrDefault(pattern, new SimpleDateFormat(pattern));
sdfMap.putIfAbsent(pattern, sdf);
return sdf.format(date);
}
}
上面的代码中,使用ConcurrentHashMap缓存已经创建的SimpleDateFormat对象,避免了重复创建。
六、小结
本文主要介绍了SimpleDateFormat类,包括如何将日期格式化为YYYYMMDD格式、如何将字符串解析为日期对象、如何避免线程安全问题以及如何进行性能优化等方面。
SimpleDateFormat是Java日期处理中非常常用的一个类,需要经常使用。在使用时,要注意线程安全问题和性能优化。