Skip to content

DateTimeFormatter

格式化与解析

DateTimeFormatter 是 JDK 8 引入的日期时间格式化类,它是 线程安全 的,可以安全地在多线程环境中共享使用。

这解决了 SimpleDateFormat 的线程安全问题。

基本用法

格式化(LocalDateTime → String)

java
LocalDateTime dt = LocalDateTime.of(2026, 3, 22, 14, 30, 45);

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = dt.format(formatter);
System.out.println(formatted); // 2026-03-22 14:30:45

解析(String → LocalDateTime)

java
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String str = "2026-03-22 14:30:45";

LocalDateTime dt = LocalDateTime.parse(str, formatter);
System.out.println(dt); // 2026-03-22T14:30:45

常用格式符号

符号含义示例
yyyyy = 2026
MMM = 03, MMM = 三月
ddd = 22
E星期E = 日, EEEE = 星期日
H24 小时HH = 14
h12 小时hh = 02
mmm = 30
sss = 45
S毫秒SSS = 123
a上午/下午a = 下午
z时区名z = CST

预定义格式

JDK 内置了很多常用格式:

java
// ISO 标准格式
LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
// 2026-03-22T14:30:45

LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
// 2026-03-22

LocalTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME);
// 14:30:45

Instant.now().format(DateTimeFormatter.ISO_INSTANT);
// 2026-03-22T06:30:45.123456789Z

// BASIC ISO
LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE);
// 20260322

// 本地化格式
LocalDate.now().format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL));
// 2026年3月22日 星期日

LocalDate.now().format(DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG));
// 2026年3月22日

LocalDate.now().format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM));
// 2026-3-22

LocalDate.now().format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT));
// 26/3/22

常用场景

日期格式化

java
// 2026-03-22
LocalDate date = LocalDate.now();
String s1 = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

// 2026年03月22日
String s2 = date.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"));

// 2026/03/22
String s3 = date.format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));

日期时间格式化

java
LocalDateTime dt = LocalDateTime.now();

// 2026-03-22 14:30:45
String s1 = dt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

// 2026/03/22 14:30
String s2 = dt.format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm"));

// 14:30:45 2026-03-22
String s3 = dt.format(DateTimeFormatter.ofPattern("HH:mm:ss yyyy-MM-dd"));

带星期和上下午

java
LocalDateTime dt = LocalDateTime.of(2026, 3, 22, 14, 30);

// 2026年3月22日 星期日 下午 14:30
String formatted = dt.format(DateTimeFormatter.ofPattern("yyyy年M月d日 E a HH:mm"));
System.out.println(formatted);

带毫秒

java
LocalDateTime dt = LocalDateTime.now();

// 带毫秒
String withMillis = dt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
// 2026-03-22 14:30:45.123

带时区的格式化

java
ZonedDateTime zdt = ZonedDateTime.now();

// 2026-03-22T14:30:45+08:00[Asia/Shanghai]
String isoZoned = zdt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME);

// 自定义格式带时区
String custom = zdt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss XXX"));
// 2026-03-22 14:30:45 +08:00

解析带中文

java
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年M月d日");

LocalDate date = LocalDate.parse("2026年3月22日", formatter);
System.out.println(date); // 2026-03-22

线程安全

DateTimeFormatter 是线程安全的:

java
public class DateTimeUtil {
    // 可以作为静态常量,安全共享
    private static final DateTimeFormatter DATE_FORMATTER =
        DateTimeFormatter.ofPattern("yyyy-MM-dd");

    private static final DateTimeFormatter DATETIME_FORMATTER =
        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    public static String formatDate(LocalDate date) {
        return date.format(DATE_FORMATTER);
    }

    public static String formatDateTime(LocalDateTime dt) {
        return dt.format(DATETIME_FORMATTER);
    }
}

多线程直接调用,不会出问题:

java
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < 100; i++) {
    executor.submit(() -> {
        String result = DateTimeUtil.formatDate(LocalDate.now());
        // 安全!
    });
}

与 SimpleDateFormat 对比

方面SimpleDateFormatDateTimeFormatter
线程安全
格式支持有限丰富
时区麻烦方便
API 设计混乱清晰

总结

DateTimeFormatter 的优势:

  1. 线程安全:可以安全地共享实例
  2. 格式丰富:支持 ISO 标准、本地化、自定义格式
  3. API 清晰:格式化/解析职责分明
  4. 支持时区:ZonedDateTime 格式化也很方便

记住:format() 用于格式化,parse() 用于解析。

基于 VitePress 构建