Joda.Time DateTimeFormat转换短月份缩写日期时抛出格式无效异常排查
问题原因与解决方案
核心问题
你遇到的异常源于Joda Time的日期模式匹配规则和输入的格式、大小写不兼容:
- Joda Time中,
MMM模式对应月份缩写(如英文Locale下的Sep),MMMM才对应月份全拼(September)。你用ddMMMyyyy能解析全拼的September属于Joda Time的宽松匹配特例,不具备通用性。 - 默认的
MMM解析器区分大小写,而你输入的是小写的sep,和英文Locale中首字母大写的月份缩写Sep不匹配,因此抛出格式无效的异常。
修复方案
要同时支持小写缩写(如sep)和全拼(如September)的日期解析,需要用DateTimeFormatterBuilder构建支持多模式、不区分大小写的解析器,替代直接用DateTimeFormat.forPattern的方式。
修改后的Scala代码如下:
import org.joda.time.DateTime import org.joda.time.format.{DateTimeFormatter, DateTimeFormatterBuilder} import scala.util.{Failure, Success, Try} def dateFormatter(date: String, inputPatterns: Seq[String], outputFormat: String): String = { val outputFormatter = DateTimeFormat.forPattern(outputFormat) // 构建支持多模式、不区分大小写的解析器 val inputFormatter = new DateTimeFormatterBuilder() .append(null, inputPatterns.map(DateTimeFormat.forPattern(_).getParser).toArray) .toFormatter() .withLocale(java.util.Locale.ENGLISH) // 指定英文Locale,确保月份匹配 .parseCaseInsensitive() // 开启大小写不敏感解析 Try { Option(date) .map(_.trim) .filter(_.nonEmpty) .map(inputFormatter.parseDateTime) .map(outputFormatter.print) .orNull } match { case Success(result) => result case Failure(e) => println(s"解析异常: ${e.getMessage}") date } } // 调用示例:同时传入全拼和缩写模式 val result1 = dateFormatter("09September2032", Seq("ddMMMMyyyy", "ddMMMyyyy"), "yyyy-MM-dd") val result2 = dateFormatter("09sep2032", Seq("ddMMMMyyyy", "ddMMMyyyy"), "yyyy-MM-dd") println(result1) // 输出2032-09-09 println(result2) // 输出2032-09-09
关键修改点
- 用
DateTimeFormatterBuilder组合多个解析模式(ddMMMMyyyy和ddMMMyyyy),同时支持全拼和缩写月份。 - 开启
parseCaseInsensitive(),让解析器忽略大小写,匹配小写的sep。 - 明确指定英文Locale,避免系统默认Locale导致的月份名称不匹配问题。
内容的提问来源于stack exchange,提问作者Ignacio Alorre
相关产品推荐
相关产品推荐

