DateTimeFormatter 是 Java 8 引入的日期时间格式化工具类,位于 java.time.format 包下,用于格式化日期时间对象为字符串和解析字符串为日期时间对象。它替代了旧版的 SimpleDateFormat,核心优势是不可变且线程安全,可在多线程环境中安全使用。
DateTimeFormatter 提供了多种预定义的格式化器,覆盖常见的标准格式(如 ISO 规范)和本地化格式,无需手动定义模式。
常用预定义格式化器 | 说明 | 示例输出 |
ISO_LOCAL_DATE | 本地日期(ISO 格式:yyyy-MM-dd) | 2023-10-05 |
ISO_LOCAL_TIME | 本地时间(ISO 格式:HH:mm:ss) | 14:30:25 |
ISO_LOCAL_DATE_TIME | 本地日期时间(ISO 格式:yyyy-MM-ddTHH:mm:ss) | 2023-10-05T14:30:25 |
ISO_ZONED_DATE_TIME | 带时区的日期时间 | 2023-10-05T14:30:25+08:00 |
ofLocalizedDate() | 本地化日期(如中文环境:2023 年 10 月 5 日) | 2023年10月5日 |
示例:使用预定义格式化器
package com.hxstrive.java_date_time.dateTimeFormatter; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class DateTimeFormatterDemo { public static void main(String[] args) { // 格式化LocalDate为ISO日期字符串 LocalDate date = LocalDate.of(2023, 10, 5); String dateStr = date.format(DateTimeFormatter.ISO_LOCAL_DATE); System.out.println("ISO日期:" + dateStr); // 输出:2023-10-05 // 格式化LocalDateTime为ISO日期时间字符串 LocalDateTime dateTime = LocalDateTime.of(2023, 10, 5, 14, 30, 25); String dateTimeStr = dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME); System.out.println("ISO日期时间:" + dateTimeStr); // 输出:2023-10-05T14:30:25 } }
运行结果:
ISO日期:2023-10-05 ISO日期时间:2023-10-05T14:30:25
通过模式字符串定义自定义格式,模式字母与 SimpleDateFormat 类似,但需注意大小写敏感(如 M 表示月,m 表示分钟)。
常用模式字母如下:
y:年(如yyyy表示 4 位年,yy表示 2 位年)
M:月(如MM表示 2 位月,MMM表示英文缩写,MMMM表示英文全称)
d:日(dd表示 2 位日)
H:24 小时制小时(HH表示 2 位)
h:12 小时制小时(hh表示 2 位)
m:分钟(mm表示 2 位)
s:秒(ss表示 2 位)
a:上午 / 下午(与 12 小时制配合使用,如hh:mm:ss a)
E:星期(E表示缩写,EEEE表示全称)
示例:自定义格式化器
package com.hxstrive.java_date_time.dateTimeFormatter; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class CustomFormatterDemo { public static void main(String[] args) { // 定义自定义模式:"yyyy年MM月dd日 HH:mm:ss 星期E" DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss 星期E"); // 格式化LocalDateTime LocalDateTime now = LocalDateTime.now(); String formatted = now.format(formatter); System.out.println("自定义格式:" + formatted); // 输出示例:2023年10月05日 14:35:42 星期四 } }
运行结果:
自定义格式:2025年09月21日 22:55:02 星期周日
将 LocalDate、LocalDateTime 等实现 TemporalAccessor 接口的日期时间对象,格式化为字符串。例如:
package com.hxstrive.java_date_time.dateTimeFormatter; import java.time.LocalDate; import java.time.format.DateTimeFormatter; public class FormatDemo { public static void main(String[] args) { LocalDate date = LocalDate.of(2023, 12, 25); // 自定义格式:"MM/dd/yyyy"(月/日/年) DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy"); String result = formatter.format(date); // 等价于 date.format(formatter) System.out.println("格式化结果:" + result); // 输出:12/25/2023 } }
运行结果:
格式化结果:12/25/2023
将字符串按格式化器的规则解析为 TemporalAccessor 对象,需配合 LocalDate.parse()、LocalDateTime.parse() 等方法转换为具体类型。
注意:解析的字符串必须严格匹配格式化器的模式,否则会抛出 DateTimeParseException。
示例:
package com.hxstrive.java_date_time.dateTimeFormatter; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; public class ParseDemo { public static void main(String[] args) { String str = "2023-10-05 15:30:45"; // 定义与字符串匹配的模式 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); try { // 解析为LocalDateTime LocalDateTime dateTime = LocalDateTime.parse(str, formatter); System.out.println("解析结果:" + dateTime); // 输出:2023-10-05T15:30:45 } catch (DateTimeParseException e) { System.out.println("解析失败:" + e.getMessage()); } } }
运行结果:
解析结果:2023-10-05T15:30:45
模式字母大小写敏感:
M(月)和m(分钟)不可混用。
H(24 小时制)和h(12 小时制)需根据需求选择,12 小时制通常配合a(上午 / 下午)使用。
解析严格匹配:
字符串格式必须与模式完全一致(如模式为yyyy-MM-dd,字符串2023/10/05会解析失败)。
数值需合法(如月份不能为 13,日期不能超过当月最大天数)。
线程安全:
DateTimeFormatter 是不可变对象,可作为静态常量全局共享,无需每次使用时创建。
本地化支持:
如需适配不同地区的日期格式(如中文 “年/月/日”、英文“MM/dd/yyyy”),可使用 withLocale() 方法指定 locale:
DateTimeFormatter chinaFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日") .withLocale(Locale.CHINA);
总的说来,DateTimeFormatter 相比旧版 SimpleDateFormat,它解决了线程安全问题,同时提供了更灵活的格式化和解析能力。实际开发中,优先使用预定义格式化器,如需自定义格式则注意模式字母的正确使用,解析时需处理可能的异常。