Java时间格式化

常见时间格式化

public static void main(String[] args) {
    Date now = new Date(); // 创建一个Date对象,获取当前时间
    String strDateFormat = "yyyy-MM-dd HH:mm:ss";

    //基本实现
    SimpleDateFormat f = new SimpleDateFormat(strDateFormat);
    System.out.println("SimpleDateFormat:" + f.format(now)); // 将当前时间袼式化为指定的格式

    //java8进阶实现
    LocalDateTime localDateTime = now.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    String result =  localDateTime.format(DateTimeFormatter.ofPattern(strDateFormat));
    System.out.println("DateTimeFormatter:"+result);

    //common-lang3老鸟实现
    result  = DateFormatUtils.format(now,strDateFormat);
    System.out.println("DateFormatUtils:"+result);

}

解析

方式一

Java8之前,JDK默认提供的时间格式化实现方式,最大的问题就是线程安全

在多线程环境下,多个线程同时使用相同的SimpleDateFormat对象,调用format方法时,多线程会同时调用calender.setTime方法,导致time被别的线程修改

Date now = new Date(); // 创建一个Date对象,获取当前时间
String strDateFormat = "yyyy-MM-dd HH:mm:ss";SimpleDateFormat f = new SimpleDateFormat(strDateFormat);
System.out.println("SimpleDateFormat:" + f.format(now)); // 将当前时间袼式化为指定的格式

解决方案:

  1. SimpleDateFormat定义为局部变量

  2. synchronized

  3. ThreadLocal

方式二

Java8后,推荐使用DateTimeFormatter代替SimpleDateFormat

DateTimeFormatter是线程安全的,默认提供了很多格式化方式,也可以通过ofPattern方法创建自定义格式化方法

//java8进阶实现
LocalDateTime localDateTime = LocalDateTime.now();
String result =  localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println("DateTimeFormatter:"+result);

需要注意,这些方式都是针对LocalDateLocalDateTime对象的,其中LocalDateTime包含时分秒,而LocalDate只包含年月日,没有时分秒信息

Java8新增日期时间API,新增了LocalDateLocalDateTimeLocalTime等线程安全类:

LocalDate:只有日期,诸如:1991-12-25
LocalTime:只有时间,诸如:09:30
LocalDateTime:日期+时间,诸如:1991-12-25 09:30

Date转Local……
//Date转LocalDate
public static LocalDate date2LocalDate(Date date) {
    if(null == date) {
        return null;
    }
    return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
}
//Date转LocalDateTime
public static LocalDateTime date2LocalDateTime(Date date) {
    if(null == date) {
        return null;
    }
    return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
}
//LocalDate转Date
public static Date localDate2Date(LocalDate localDate) {
    if(null == localDate) {
        return null;
    }
    ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
    return Date.from(zonedDateTime.toInstant());
}
//LocalDateTime转Date
public static Date localDateTime2Date(LocalDateTime localDateTime) {
    return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}

方式三

相信大家在项目开发过程中都多少使用过common-lang3中的一些API,都非常简单实用。在时间格式化方面,也给我们提供了非常好用的工具类DateFormatUtils

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.11</version>
</dependency>
Date now = new Date(); // 创建一个Date对象,获取当前时间
String strDateFormat = "yyyy-MM-dd HH:mm:ss";
String result  = DateFormatUtils.format(now,strDateFormat);
System.out.println("DateFormatUtils:"+result);

此方法是线程安全的,简单高效,占用内存小

DateFormatUtils.format的内部实现中,是通过FastDateFormat进行时间格式化,而且对FastDateFormat对象进行了缓存处理,保证相同模式的格式化类型下不用重复生成FastDateFormat对象。

FastDateFormat df = FastDateFormat.getInstance(pattern, timeZone, locale);

推荐使用方式:

/**
 * @Description   时间格式化工具类
 * @Date 2022/10/27 16:40 上午
 */
public class DateUtils extends DateFormatUtils {
      //继承DateFormatUtils
      //自定义的时间相关方法
}

参考

文章1:https://blog.csdn.net/w1014074794/article/details/117112128