带有liternal且没有分隔符的DateTimeFormatter模式不起作用 [英] DateTimeFormatter pattern with liternal and no separator does not work

查看:95
本文介绍了带有liternal且没有分隔符的DateTimeFormatter模式不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

DateTimeFormatter.ofPattern生成的解析器表现出以下有趣的行为,这阻止了我编写模式来解析诸如20150100的字符串:

The parser generated by DateTimeFormatter.ofPattern exhibits the following interesting behaviour which is preventing me from writing a pattern to parse a string like 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

我调试了代码,看来问题出在字符串末尾之外的年份字段解析(三个y或更大的最大宽度始终为19)引起的.但是,我不明白如果没有结尾的'00'文字,该模式如何对模式起作用.

I debuged the code, it seems the problem is caused by the year field parsing beyond the end of the string (max width for three y's and more is always 19). However, I don't understand how it could work for the pattern without the '00' literal at the end.

是否有任何方法可以不必使用格式化程序生成器来解决此问题?

Is there any way to fix this withing having to use a formatter builder?

由于下面的Jarrod确认它存在错误,因此我进行了更多的谷歌搜索并最终发现了错误报告:

Since Jarrod below confirmed it's buggy, I did more googling and finally found the bug reports:

http://bugs.java.com/bugdatabase/view_bug.do? bug_id = 8031085

http://bugs.java.com/bugdatabase/view_bug.do? bug_id = 8032491

尽管两者都仅在Java 9中已修复...

Both are only fixed in Java 9 though......

推荐答案

DateTimePrinterParser中存在错误:

我逐步调试了整个过程,显然您不能将数字用作文字.如果从头开始调试DateTimeFormatterBuilder.parse()方法,类似的测试代码也可以证明这一点.

There is a bug in the DateTimePrinterParser:

I step debugged all the way through it, apparently you can not have digits as literals. Similar test codes proves this if you step debug all the way through to the DateTimeFormatterBuilder.parse() method you can see what it is doing wrong.

显然,如果Value(YearOfEra,4,19,EXCEEDS_PAD)解析器使用的是数字,则它们会在00处停止,因为它们正在寻找一个长度为419位的数字.嵌入在DateTimeParseContext中的DateTimeFormatter是错误的.

Apparently the Value(YearOfEra,4,19,EXCEEDS_PAD) parser consumes the 00 where they stop if those are not digits because it is looking for a number 4 to 19 digits long. The DateTimeFormatter that is embedded in the DateTimeParseContext is wrong.

如果您使用非数字字符文字(如xx)有效,则数字文字不起作用.

If you put a non-digit character literal like xx it works, digit literals don't.

final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM'00'");
System.out.println(sdf.parse("20150100"));

线程主"中的异常java.text.ParseException:无法解析的日期: java.text.DateFormat.parse(DateFormat.java:366)的"20150100"

Exception in thread "main" java.text.ParseException: Unparseable date: "20150100" at java.text.DateFormat.parse(DateFormat.java:366)

final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMM'00'");
System.out.println(dateTimeFormatter.parse("20150100", YearMonth::from));

线程"main"中的异常java.time.format.DateTimeParseException: 无法在索引0处解析文本"20150100" java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949) 在 java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)

Exception in thread "main" java.time.format.DateTimeParseException: Text '20150100' could not be parsed at index 0 at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949) at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)

这两个都成功:

final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM'xx'");
System.out.println(sdf.parse("201501xx"));

美国东部时间2015年1月1日星期四00:00:00

Thu Jan 01 00:00:00 EST 2015

final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMM'xx'");
System.out.println(dateTimeFormatter.parse("201501xx", YearMonth::from));

2015-01

2015-01

这篇关于带有liternal且没有分隔符的DateTimeFormatter模式不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆