Java DateTimeFormatter 不适用于模式“ddMyyyy”,

Java DateTimeFormatter Not Working for Pattern 'ddMyyyy'

提问人:Twisted Tea 提问时间:8/19/2023 更新时间:10/7/2023 访问量:119

问:

请考虑以下日期:

String date = "2391995";
String patt = "ddMyyyy";

使用提供的模式,我们可以看到它表示 1995 年 9 月 23 日。date

但是考虑一下尝试解析它时会发生什么 - 首先是旧方法,然后是 Java 8+ 方法:

Date dd = new SimpleDateFormat(patt).parse(date);
System.out.println(dd);
        
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(patt);
LocalDate d = LocalDate.parse(date, formatter);
System.out.println(d);

输出:

Sat Sep 23 00:00:00 EDT 1995
Exception in thread "main" java.time.format.DateTimeParseException: Text '2391995' could not be parsed at index 7
    ...

正如我们所看到的,旧的方式,按预期使用工作。但是当使用 和 时,会发生错误。为什么会这样?SimpleDateFormatDateTimeFormatterLocalDate.parse

java 日期 日期、时间、 文本解析

评论

2赞 cliff2310 8/19/2023
1102023 (2023年10月1日)呢?我认为您将需要“ddMMyyyy”,因为“ddMyyyy”可能不是有效的日期格式。
0赞 Twisted Tea 8/19/2023
特别是在这种情况下,@cliff2310我相信我看到了一种解决方法(没有零月份,所以 110 必须指 10/1),但我想如果我们考虑类似 1112023 的东西,我会明白你的意思(111 是模棱两可的,可以指 11-1 或 1-11)。不幸的是,我无法控制格式
0赞 Anonymous 8/19/2023
首先,您显然不能以这种方式表示一年中的所有月份。如果是出于特殊目的,那可能是可以的。其次,我相信您可以使用 a 来指定 1 位数字的月份,这样构建一个可以解析为 .DateTimeFormatterBuilderDateTimeFormatterLocalDate
0赞 Twisted Tea 8/19/2023
@OleV.V ...当然,你不能用 1 位数字表示一年中的所有月份,历史上指的是没有零填充的月份(8、9、10 而不是 08、09、10)M
0赞 Reilas 8/19/2023
一个有趣的错误;月份应该与 区分开来,而不是单个 。ddd

答:

7赞 Diego Borba 8/19/2023 #1

模式之所以有效,但不能使用,是因为这两个类之间的模式符号及其解释存在差异。ddMyyyySimpleDateFormatDateTimeFormatter

SimpleDateFormat用于解析和格式化日期,但它们具有不同的模式符号和行为集。DateTimeFormatter

在 中,模式符号以数字形式表示月份,用于处理个位数和两位数的月份。因此,在您的原始模式中,该符号被解释为个位数的月份,这就是它与输入一起使用的原因(假设它是 )。SimpleDateFormatMddMyyyyM"2391995""23/9/1995"

另一方面,在 中,模式符号专门用于解析个位数或两位数的月份,但它需要一个月份值,其中包含一个表示个位数月份的前导零。由于您的输入具有个位数的月份 (9),因此它没有前导零,这就是该模式未按预期工作的原因。DateTimeFormatterM"2391995"ddMyyyy

就像我说的,要解决,你可以包含一个前导零,但你也可以这样拆分值:

String date = "23 9 1995";
String patt = "dd M yyyy";

看看这个:

评论

1赞 Diego Borba 8/19/2023
完全。但你也可以这样拆分 和 ,: & .我会把这个放在我的答案中。datepattString date = "23 9 1995"String patt = "dd M yyyy"
1赞 Reilas 8/19/2023
@DiegoBorba,你有这方面的参考吗?我在 JavaDoc 中找不到它。
1赞 Diego Borba 8/19/2023
但我说“M 模式符号专门用于解析个位数或两位数的月份”。
2赞 user16320675 8/19/2023
顺便说一句,结果LocalDate.parse("7 0009 1822", DateTimeFormatter.ofPattern("d M y"))1822-09-07
1赞 Anonymous 8/20/2023
对于数字字段,单个字母的意思是“尽可能多的数字”(所以正如你所说,它并不意味着“1 位数字”)。不幸的是,这没有得到很好的记录。不幸的是,几个月来,它不限于两位数。例如,它也接受 9 月,这对我来说没有意义。009