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常用格式符号
| 符号 | 含义 | 示例 |
|---|---|---|
| y | 年 | yyyy = 2026 |
| M | 月 | MM = 03, MMM = 三月 |
| d | 日 | dd = 22 |
| E | 星期 | E = 日, EEEE = 星期日 |
| H | 24 小时 | HH = 14 |
| h | 12 小时 | hh = 02 |
| m | 分 | mm = 30 |
| s | 秒 | ss = 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 对比
| 方面 | SimpleDateFormat | DateTimeFormatter |
|---|---|---|
| 线程安全 | 否 | 是 |
| 格式支持 | 有限 | 丰富 |
| 时区 | 麻烦 | 方便 |
| API 设计 | 混乱 | 清晰 |
总结
DateTimeFormatter 的优势:
- 线程安全:可以安全地共享实例
- 格式丰富:支持 ISO 标准、本地化、自定义格式
- API 清晰:格式化/解析职责分明
- 支持时区:ZonedDateTime 格式化也很方便
记住:format() 用于格式化,parse() 用于解析。
