DateFormat
类的解析方法如果成功解析字符串开头的日期,则忽略尾随文本。
API docs回避:
Parses text from the beginning of the given string to produce a date. The method may not use the entire text of the given string.
我认为“可能”的意思是 - “如果尾随文本存在并且不是日期的一部分(不能这样解释)”。但看起来这个“可能”更难以预测。
给定
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
这不正确(意外):
System.out.println(df.parse("2019-12-112"));
Output: Sat Mar 21 00:00:00 MSK 2020
虽然这工作正常(如预期):
System.out.println(df.parse("2019-12-11sometext"));
Output: Wed Dec 11 00:00:00 MSK 2019
如果解析文本的其余部分是数字,它似乎总是无法正确解析(给出不同的错误结果):
System.out.println(df.parse("2019-12-1189"));
System.out.println(df.parse("2019-12-11234"));
Output:
Fri Mar 03 00:00:00 MSK 2023
Fri Sep 02 00:00:00 MSK 2050
现在,setLenient()
的行为如下:
- 如果(正确的)日期后跟一个空格或字母,则 setLenient() 设置没有区别。 setLenient (true/false) 的所有内容均已正确解析且无一异常(exception)。
- 但是如果(正确的)日期后面紧跟着数字,那么 setLenient() 确实会产生(意想不到的)差异:默认值(true)不会产生异常,并且错误的(!)解析结果,但是 setLenient(false) 会导致
ParseException: Unparseable date: "2019-12-111"
这也很奇怪(日期是正确的并且忽略尾随文本是 API promise 的)。 ..
Date parse(String source, ParsePosition pos)
在上述所有情况下(包括对 setLenient 的 react )与 Date parse(String source)
的行为完全相同(和预期的)异常,其中一个参数 parse() 抛出 ParseException,这个两个参数 parse() 返回 null(这是它对要解析的字符串开头的错误日期格式的 react )。
还值得注意的是,在调用 mydateFormat.parse("2019-12-11234", pos)
(使用 setLenient(true))之后,pos。 getIndex()
返回 13 - 指向“超出”234 部分,这意味着它将这 234 部分视为 new SimpleDateFormat("yyyy -MM-dd")
.
附言我知道这些是过时的日期/时间 API,我更喜欢 java.time 而不是 Date/Calendar/DateFormat 等。但它仍然大量存在于遗留代码中,以在无法进行重构的情况下提供支持。
最佳答案
当您将 isLenient 设置为 true 并添加额外数字时,格式化程序将尝试根据给定值计算新日期,因此 df.parse("2019-12-1189")
将被解析为2019-12-01 + 1189 天 (1189/365 = 3.26) 所以 Fri Mar 03 00:00:00 MSK 2023 看起来是正确的结果(我不知道这里的确切数学)。
与 11234 相同,增加了大约 30 年。
您也可以尝试将 2019-12-32 和 2019-13-01 都转换为 2020-01-01
关于java - DateFormat.parse(String) 究竟如何处理非日期尾随文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56901882/