如何正确解析并格式化 Java 中的日期字符串

本文详解如何解决 `datetimeparseexception` 异常,通过为解析和格式化分别配置匹配的 `datetimeformatter`,将 `"2025-01-25"` 正确转换为 `"jan 25, 2025"`。

该异常的根本原因在于:解析器的模式与输入字符串格式不匹配。在原始代码中,你使用了 DateTimeFormatter.ofPattern("MMM dd, yyyyy")(如 "Jan 25, 2025")去尝试解析形如 "2025-01-25" 的字符串——这就像用英文词典查中文单词,必然失败。LocalDate.parse() 要求格式器能准确识别输入文本的结构,否则在索引 0 处(即第一个字符)就抛出 DateTimeParseException。

✅ 正确做法是「解析」与「格式化」职责分离:

  • 解析(Parse):使用与输入字符串完全一致的模式(如 "yyyy-MM-dd")构建 DateTimeFormatter,用于将字符串转为 LocalDate 对象;
  • 格式化(Format):另用目标显示格式(如 "MMM dd, yyyy")构建另一个 DateTimeFormatter,调用 localDate.format() 得到所需字符串。

以下是完整、可运行的示例代码:

String inputString = "2025-01-25";
// ✅ 步骤1:用匹配输入格式的 formatter 解析
DateTimeFormatter parser = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate date = LocalDate.parse(inputString, parser);

// ✅ 步骤2:用目标显示格式的 formatter 格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd, yyyy", Locale.ENGLISH);
String outputString = date.format(formatter);

System.out.println(outputString); // 输出:Jan 25, 2025

⚠️ 注意事项:

  • MMM 表示缩写月份名(如 Jan),依赖 Locale。强烈建议显式传入 Locale.ENGLISH,避免因系统默认区域设置导致解析失败(例如某些 locale 下 Jan 不被识别);
  • yyyyy 是常见笔误(多写了一个 y),应为 yyyy;年份符号个数不影响解析,但语义上 yyyy 更规范;
  • LocalDate 本身不存储格式信息,其 toString() 永远返回 ISO_LOCAL_DATE 格式(如 "2025-01-25")。若需自定义显示,请始终调用 .format(formatter);
  • 若输入可能为空或格式不固定,建议配合 try-catch 或使用 DateTimeFormatterBuilder 构建更健壮的解析器。

总结:Java 8+ 的 java.time API 强调「不可变性」与「职责分离」。一次 DateTimeFormatter 只应承担单一角色——要么精准解析,要么清晰格式化。理解并遵循

这一原则,即可彻底规避此类 DateTimeParseException。