您的位置:

SimpleDateFormat格式化日期为YYYYMMDD

一、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日期处理中非常常用的一个类,需要经常使用。在使用时,要注意线程安全问题和性能优化。