Java 8 的 DateTimeFormatter 是线程安全、不可变的日期时间格式化与解析工具,提供预定义格式器(如 ISO_LOCAL_DATE_TIME)和自定义模式(如 yyyy-MM-dd HH:mm:ss),支持时区、本地化及严格解析策略。

Java 8 引入的 java.time API 提供了线程安全、不可变且语义清晰的日期时间处理方式,DateTimeFormatter 是其中专门用于格式化(输出)和解析(输入)的核心工具。它取代了老式的 SimpleDateFormat,避免了线程安全问题,也更易用、更灵活。
常用预定义格式器直接使用
对于常见格式,Java 内置了标准化的静态常量,无需手动写模式字符串:
-
DateTimeFormatter.ISO_LOCAL_DATE→2024-05-20 -
DateTimeFormatter.ISO_LOCAL_TIME→14:30:45 -
DateTimeFormatter.ISO_LOCAL_DATE_TIME→2024-05-20T14:30:45 -
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")→ 自定义,如2024-05-20 14:30:45
示例:
LocalDateTime now = LocalDateTime.now();
String s1 = now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME); // 2024-05-20T14:30:45.123
String s2 = now.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm")); // 2024年05月20日 14:30
自定义模式字符串要记清常用符号
使用 ofPattern() 时,模式字母大小写敏感,关键符号含义如下:
立即学习“Java免费学习笔记(深入)”;
-
y:年(推荐用
yyyy,yy会截取两位,可能出错) -
M:月(
MM表示数字 01–12,MMM表示英文缩写如 May,MMMM表示全称 May) -
d:日(
dd表示 01–31) -
H:24 小时制小时(
HH),h 是 12 小时制(需配合 a 使用) -
m:分钟(
mm),s:秒(ss) -
S:毫秒(
SSS表示三位数,如 012) -
a:AM/PM 标记(配合
h使用)
注意:中文环境默认不自动本地化月份/星期名,如需显示“五月”,需显式指定 Locale.CHINA:
DateTimeFormatter f = DateTimeFormatter.ofPattern("yyyy年M月d日 E HH:mm", Locale.CHINA);
String text = LocalDateTime.now().format(f); // 2024年5月20日 周一 14:30
格式化带时区的时间要选对类型
不同时间类型对应不同格式器策略:
-
LocalDateTime没有时区信息,不能用含 Z 或 z 的模式(如HH:mm:ss.SSSZ),否则抛UnsupportedTemporalTypeException -
ZonedDateTime或OffsetDateTime才支持时区输出:z→ 缩写(CST、PST),zzzz→ 全称(China Standard Time)Z→ RFC 822 格式偏移(+0800),XXX→ ISO 8601 偏移(+08:00)
正确示例:
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
String s = zdt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS zzzz XXX"));
// → 2024-05-20 14:30:45.123 China Standard Time +08:00
解析字符串时要注意严格性与异常处理
DateTimeFormatter 也可用于将字符串转为时间对象(parse()),但默认较宽松(如允许单数字月/日)。如需严格校验,可设置解析策略:
-
formatter.withResolverStyle(ResolverStyle.STRICT):拒绝 2024-02-30 这类非法日期 -
formatter.withResolverStyle(ResolverStyle.LENIENT):自动换算(如 2024-02-30 → 2024-03-01) - 务必捕获
DateTimeParseException,不要假设输入一定合法
示例:
DateTimeFormatter f = DateTimeFormatter.ofPattern("yyyy-MM-dd").withResolverStyle(ResolverStyle.STRICT);
try {
LocalDate.parse("2024-02-30", f); // 抛 DateTimeParseException
} catch (DateTimeParseException e) {
System.err.println("日期格式错误或不存在:" + e.getMessage());
}


















