Java DateTimeFormatter 类
DateTimeFormatter 是 Java 8 引入的日期时间 API (java.time 包) 中的一个重要类,它用于格式化和解析日期时间对象。这个类提供了强大的功能来处理日期时间的显示和转换。
简单来说,DateTimeFormatter 主要有两个作用:
- 格式化:将日期时间对象(如 LocalDate, LocalDateTime)转换为特定格式的字符串
- 解析:将符合格式的字符串转换为日期时间对象
为什么需要 DateTimeFormatter
在 Java 8 之前,我们使用 SimpleDateFormat 来处理日期格式化和解析,但它有几个缺点:
- 不是线程安全的
- 设计较为陈旧
- 错误处理不够友好
DateTimeFormatter 解决了这些问题:
- 线程安全:可以安全地在多线程环境中共享实例
- 不可变:一旦创建就不能被修改
- 更丰富的预定义格式:提供了大量内置格式
- 更好的错误处理:解析失败时会提供更详细的错误信息
基本使用方法
预定义的格式化器
DateTimeFormatter 提供了许多预定义的格式化常量:
实例
LocalDateTime now = LocalDateTime.now();
// 使用预定义的格式化器
System.out.println(now.format(DateTimeFormatter.ISO_LOCAL_DATE)); // 2023-11-15
System.out.println(now.format(DateTimeFormatter.ISO_LOCAL_TIME)); // 14:30:45.123
System.out.println(now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); // 2023-11-15T14:30:45.123
// 使用预定义的格式化器
System.out.println(now.format(DateTimeFormatter.ISO_LOCAL_DATE)); // 2023-11-15
System.out.println(now.format(DateTimeFormatter.ISO_LOCAL_TIME)); // 14:30:45.123
System.out.println(now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); // 2023-11-15T14:30:45.123
自定义模式
你可以使用模式字符串创建自定义的格式化器:
实例
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDateTime = now.format(formatter); // 格式化
System.out.println(formattedDateTime); // 2023-11-15 14:30:45
// 解析
LocalDateTime parsedDateTime = LocalDateTime.parse("2023-11-15 14:30:45", formatter);
// 常用中文日期格式
DateTimeFormatter chineseFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
String formattedDate = today.format(chineseFormatter);
System.out.println("中文格式日期: " + formattedDate);
// 解析中文日期字符串
String chineseDateStr = "2023年05月20日";
LocalDate parsedDate = LocalDate.parse(chineseDateStr, chineseFormatter);
System.out.println("解析后的日期: " + parsedDate);
// 其他常用格式
DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("MM/dd/yyyy");
DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 EEEE", Locale.CHINA);
System.out.println("格式1: " + today.format(formatter1));
System.out.println("格式2: " + today.format(formatter2));
System.out.println("格式3(带星期): " + today.format(formatter3));
String formattedDateTime = now.format(formatter); // 格式化
System.out.println(formattedDateTime); // 2023-11-15 14:30:45
// 解析
LocalDateTime parsedDateTime = LocalDateTime.parse("2023-11-15 14:30:45", formatter);
// 常用中文日期格式
DateTimeFormatter chineseFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
String formattedDate = today.format(chineseFormatter);
System.out.println("中文格式日期: " + formattedDate);
// 解析中文日期字符串
String chineseDateStr = "2023年05月20日";
LocalDate parsedDate = LocalDate.parse(chineseDateStr, chineseFormatter);
System.out.println("解析后的日期: " + parsedDate);
// 其他常用格式
DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("MM/dd/yyyy");
DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 EEEE", Locale.CHINA);
System.out.println("格式1: " + today.format(formatter1));
System.out.println("格式2: " + today.format(formatter2));
System.out.println("格式3(带星期): " + today.format(formatter3));
本地化格式
可以根据不同的地区创建格式化器:
实例
DateTimeFormatter frenchFormatter =
DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG)
.withLocale(Locale.FRENCH);
String frenchDate = now.format(frenchFormatter);
System.out.println(frenchDate); // 15 novembre 2023
DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG)
.withLocale(Locale.FRENCH);
String frenchDate = now.format(frenchFormatter);
System.out.println(frenchDate); // 15 novembre 2023
模式字母说明
创建自定义格式时,需要使用特定的模式字母:
字母 | 含义 | 示例 |
---|---|---|
y | 年 | yyyy → 2023 |
M | 月 | MM → 11 |
d | 日 | dd → 15 |
H | 小时(0-23) | HH → 14 |
h | 小时(1-12) | hh → 02 |
m | 分钟 | mm → 30 |
s | 秒 | ss → 45 |
S | 毫秒 | SSS → 123 |
E | 星期几 | E → 周三 |
a | 上午/下午 | a → 下午 |
最佳实践
重用格式化器
由于 DateTimeFormatter 是线程安全的,建议将常用的格式化器定义为常量:
实例
public class DateUtils {
public static final DateTimeFormatter STANDARD_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 使用方式
String formatted = LocalDateTime.now().format(STANDARD_FORMATTER);
}
public static final DateTimeFormatter STANDARD_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 使用方式
String formatted = LocalDateTime.now().format(STANDARD_FORMATTER);
}
综合实例:
实例
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class RunoobTest {
public static void main(String[] args) {
// 1. LocalDate 示例
LocalDate currentDate = LocalDate.now();
System.out.println("当前日期: " + currentDate);
LocalDate specificDate = LocalDate.of(2023, 5, 20);
System.out.println("特定日期: " + specificDate);
// 2. LocalTime 示例
LocalTime currentTime = LocalTime.now();
System.out.println("当前时间: " + currentTime);
LocalTime specificTime = LocalTime.of(14, 30, 15);
System.out.println("特定时间: " + specificTime);
// 3. LocalDateTime 示例
LocalDateTime currentDateTime = LocalDateTime.now();
System.out.println("当前日期时间: " + currentDateTime);
LocalDateTime specificDateTime = LocalDateTime.of(2023, 5, 20, 14, 30, 15);
System.out.println("特定日期时间: " + specificDateTime);
// 4. DateTimeFormatter 示例
// 基本格式化
DateTimeFormatter basicFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
System.out.println("基本格式化: " + currentDate.format(basicFormatter));
// 中文格式化
DateTimeFormatter chineseFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日", Locale.CHINA);
System.out.println("中文日期: " + currentDate.format(chineseFormatter));
// 带星期的中文格式化
DateTimeFormatter weekFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 EEEE", Locale.CHINA);
System.out.println("带星期的中文日期: " + currentDate.format(weekFormatter));
// 时间格式化
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH时mm分ss秒");
System.out.println("中文时间: " + currentTime.format(timeFormatter));
// 日期时间格式化
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println("标准日期时间: " + currentDateTime.format(dateTimeFormatter));
// 解析日期
String dateStr = "2023-05-20";
LocalDate parsedDate = LocalDate.parse(dateStr, basicFormatter);
System.out.println("解析后的日期: " + parsedDate);
// 解析中文日期
String chineseDateStr = "2023年05月20日";
LocalDate parsedChineseDate = LocalDate.parse(chineseDateStr, chineseFormatter);
System.out.println("解析后的中文日期: " + parsedChineseDate);
}
}
import java.time.LocalTime;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class RunoobTest {
public static void main(String[] args) {
// 1. LocalDate 示例
LocalDate currentDate = LocalDate.now();
System.out.println("当前日期: " + currentDate);
LocalDate specificDate = LocalDate.of(2023, 5, 20);
System.out.println("特定日期: " + specificDate);
// 2. LocalTime 示例
LocalTime currentTime = LocalTime.now();
System.out.println("当前时间: " + currentTime);
LocalTime specificTime = LocalTime.of(14, 30, 15);
System.out.println("特定时间: " + specificTime);
// 3. LocalDateTime 示例
LocalDateTime currentDateTime = LocalDateTime.now();
System.out.println("当前日期时间: " + currentDateTime);
LocalDateTime specificDateTime = LocalDateTime.of(2023, 5, 20, 14, 30, 15);
System.out.println("特定日期时间: " + specificDateTime);
// 4. DateTimeFormatter 示例
// 基本格式化
DateTimeFormatter basicFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
System.out.println("基本格式化: " + currentDate.format(basicFormatter));
// 中文格式化
DateTimeFormatter chineseFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日", Locale.CHINA);
System.out.println("中文日期: " + currentDate.format(chineseFormatter));
// 带星期的中文格式化
DateTimeFormatter weekFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 EEEE", Locale.CHINA);
System.out.println("带星期的中文日期: " + currentDate.format(weekFormatter));
// 时间格式化
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH时mm分ss秒");
System.out.println("中文时间: " + currentTime.format(timeFormatter));
// 日期时间格式化
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println("标准日期时间: " + currentDateTime.format(dateTimeFormatter));
// 解析日期
String dateStr = "2023-05-20";
LocalDate parsedDate = LocalDate.parse(dateStr, basicFormatter);
System.out.println("解析后的日期: " + parsedDate);
// 解析中文日期
String chineseDateStr = "2023年05月20日";
LocalDate parsedChineseDate = LocalDate.parse(chineseDateStr, chineseFormatter);
System.out.println("解析后的中文日期: " + parsedChineseDate);
}
}
输出结果为:
当前日期: 2025-05-01 特定日期: 2023-05-20 当前时间: 10:46:38.591747 特定时间: 14:30:15 当前日期时间: 2025-05-01T10:46:38.592002 特定日期时间: 2023-05-20T14:30:15 基本格式化: 2025-05-01 中文日期: 2025年05月01日 带星期的中文日期: 2025年05月01日 星期四 中文时间: 10时46分38秒 标准日期时间: 2025-05-01 10:46:38 解析后的日期: 2023-05-20 解析后的中文日期: 2023-05-20
处理解析异常
解析字符串时应该处理可能的异常:
实例
try {
LocalDateTime dateTime = LocalDateTime.parse("2023-11-15", formatter);
} catch (DateTimeParseException e) {
System.err.println("无法解析日期时间: " + e.getMessage());
}
LocalDateTime dateTime = LocalDateTime.parse("2023-11-15", formatter);
} catch (DateTimeParseException e) {
System.err.println("无法解析日期时间: " + e.getMessage());
}
考虑时区
如果需要处理时区,可以使用 ZonedDateTime 和特定的时区模式:
实例
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
System.out.println(zonedDateTime.format(formatter)); // 2023-11-15 14:30:45 CST
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
System.out.println(zonedDateTime.format(formatter)); // 2023-11-15 14:30:45 CST
总结
DateTimeFormatter 是 Java 8 日期时间 API 中处理格式化和解析的强大工具。相比旧的 SimpleDateFormat,它更加安全、灵活和易用。掌握 DateTimeFormatter 的使用可以让你更高效地处理各种日期时间格式需求。
记住关键点:
- 使用预定义的格式化器处理常见格式
- 使用 ofPattern() 创建自定义格式
- 考虑本地化和时区需求
- 重用线程安全的格式化器实例
- 正确处理解析异常
点我分享笔记