生成的解析器DateTimeFormatter.ofPattern表现出以下有趣的行为,这阻止了我编写模式来解析像这样的字符串20150100:
System.out.println(DateTimeFormatter.ofPattern("yyyyMM").parse("201501", YearMonth::from)); // works
System.out.println(DateTimeFormatter.ofPattern("yyyyMM'aa'").parse("201501aa", YearMonth::from)); // works
System.out.println(DateTimeFormatter.ofPattern("yyyyMM'00'").parse("20150100", YearMonth::from));
// java.time.format.DateTimeParseException: Text '20150100' could not be parsed at index 0
Run Code Online (Sandbox Code Playgroud)
我调试了代码,似乎问题是由超出字符串末尾的年份字段解析引起的(三个 y 和更多的最大宽度始终为 19)。但是,我不明白它如何在没有'00'文字的情况下适用于模式。
有没有办法解决这个问题而不必使用格式化程序构建器?
编辑:
由于下面的 Jarrod 确认它有问题,我做了更多的谷歌搜索,终于找到了错误报告:
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8031085
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8032491
两者都只在 Java 9 中修复......
小智 8
DateTimePrinterParser:我一步一步调试了它,显然你不能将数字作为文字。类似的测试代码证明了这一点,如果您逐步调试到该DateTimeFormatterBuilder.parse()方法,您可以看到它做错了什么。
显然,Value(YearOfEra,4,19,EXCEEDS_PAD)解析器消耗了00他们停止,如果这些都没有的数字,因为它正在寻找一些4以19长数字。该DateTimeFormatter嵌入的DateTimeParseContext是错误的。
如果你把一个非数字字符文字像xx它一样工作,数字文字就不会。
final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM'00'");
System.out.println(sdf.parse("20150100"));
Run Code Online (Sandbox Code Playgroud)
线程“main”中的异常 java.text.ParseException:无法解析的日期:java.text.DateFormat.parse(DateFormat.java:366) 处的“20150100”
final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMM'00'");
System.out.println(dateTimeFormatter.parse("20150100", YearMonth::from));
Run Code Online (Sandbox Code Playgroud)
线程“main”中的异常 java.time.format.DateTimeParseException:无法在 java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949) at java.time.format.DateTimeFormatter 的索引 0 处解析文本“20150100” .parse(DateTimeFormatter.java:1851)
final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM'xx'");
System.out.println(sdf.parse("201501xx"));
Run Code Online (Sandbox Code Playgroud)
美国东部时间 2015 年 1 月 1 日星期四 00:00:00
final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMM'xx'");
System.out.println(dateTimeFormatter.parse("201501xx", YearMonth::from));
Run Code Online (Sandbox Code Playgroud)
2015-01