datetimeformatter 是线程安全的不可变对象,可复用静态 final 实例;应避免方法内频繁新建,解析时需注意时区默认行为与严格模式,自定义格式可用 datetimeformatterbuilder 构建。

DateTimeFormatter 是线程安全的,无需额外加锁或每次新建实例。这是它与旧版 SimpleDateFormat 的关键区别——JDK 8 引入的 `java.time.format.DateTimeFormatter` 被设计为不可变(immutable)和无状态(stateless),所有格式化/解析操作都不修改内部字段,因此可被多个线程安全共享使用。
直接复用静态 formatter 实例
推荐使用预定义常量或自定义静态 final 实例,避免重复创建:
- 用内置常量:如
DateTimeFormatter.ISO_LOCAL_DATE、DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") - 声明为
public static final:在工具类或配置类中统一定义,全局复用 - 示例:private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
避免在方法内频繁 new 实例
虽然新建一个 DateTimeFormatter 开销不大,但无谓创建会增加 GC 压力,且失去复用优势:
- ❌ 错误写法:每次调用都
DateTimeFormatter.ofPattern("...") - ✅ 正确做法:提取为常量或依赖注入的单例 formatter
- 注意:pattern 字符串本身是轻量级的,但 formatter 构建过程包含编译解析逻辑,复用更高效
解析时注意时区与默认行为
线程安全不等于行为一致,需明确上下文以避免隐式偏差:
- 不含时区信息的字符串(如 "2024-05-20")解析后默认为系统时区的
LocalDate或LocalDateTime - 若需固定时区,建议搭配
ZonedDateTime.parse(..., formatter)或显式指定withZone(ZoneId) - 对输入格式严格时,可启用严格解析模式:
formatter.withResolverStyle(ResolverStyle.STRICT)
扩展:自定义 formatter 可配合 DateTimeFormatterBuilder
复杂格式(如可选字段、本地化文本)可用 DateTimeFormatterBuilder 构建,结果仍是线程安全的 formatter:
- builder 本身不是线程安全的,但
toFormatter()返回的 formatter 是 - 示例:static final DateTimeFormatter CUSTOM = new DateTimeFormatterBuilder().appendPattern("yyyy-MM").optionalStart().appendLiteral("-dd").optionalEnd().toFormatter();
- 构建完成后即可安全共享使用









