如何从Java DateTimeFormatter获取格式模式以生成友好的日期解析错误提示
问题解答
DateTimeFormatter 有对应获取模式字符串的实现,分JDK版本处理即可:
1. JDK 12及以上版本
JDK 12开始官方提供了公开的getPattern()方法,直接调用就能拿到和SimpleDateFormat.toPattern()效果一致的模式字符串,你的代码可以直接修改为:
try { date = java.time.LocalDate.parse(value, config.getDateFormat()); } catch (DateTimeParseException ex) { throw new MyException("Dates must be in format: " + config.getDateFormat().getPattern()); }
2. JDK 8~11版本
这几个版本的DateTimeFormatter没有公开的模式字符串获取方法,推荐两种解决方式:
- 方案1(无侵入、最推荐):自定义配置类同时持有模式字符串和格式化器实例,不用修改原有业务逻辑,示例实现:
// 自定义配置类 public class DateFormatConfig { private final String pattern; private final DateTimeFormatter formatter; public DateFormatConfig(String pattern) { this.pattern = pattern; this.formatter = DateTimeFormatter.ofPattern(pattern); } public String getPattern() { return pattern; } public DateTimeFormatter getFormatter() { return formatter; } } // 业务代码使用 try { date = LocalDate.parse(value, config.getDateFormat().getFormatter()); } catch (DateTimeParseException ex) { throw new MyException("Dates must be in format: " + config.getDateFormat().getPattern()); }
- 方案2(反射实现,适合无法修改配置结构的场景):通过反射读取
DateTimeFormatter的私有pattern字段,仅对通过ofPattern()方法生成的自定义格式化器有效,JDK内置的预定义格式化器(如DateTimeFormatter.ISO_LOCAL_DATE)无该字段:
public static String getFormatterPattern(DateTimeFormatter formatter) { try { Field field = DateTimeFormatter.class.getDeclaredField("pattern"); field.setAccessible(true); return (String) field.get(formatter); } catch (NoSuchFieldException | IllegalAccessException e) { // 内置格式化器取不到pattern的情况可以返回默认提示,或者对应本地化说明 return "yyyy-MM-dd(默认)"; } }
特殊说明
如果你使用的是ofLocalizedDate()这类基于区域生成的动态本地化格式化器,本身不存在固定的字符串模式,这种场景建议你同时存储对应的FormatStyle和Locale信息,根据区域返回对应语言的友好格式提示即可。
内容的提问来源于stack exchange,提问作者Mark Davoren
相关产品推荐
相关产品推荐

