java - DateFormat.parse(String) 究竟如何处理非日期尾随文本?

标签 java date

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() 的行为如下:

  1. 如果(正确的)日期后跟一个空格或字母,则 setLenient() 设置没有区别。 setLenient (true/false) 的所有内容均已正确解析且无一异常(exception)。
  2. 但是如果(正确的)日期后面紧跟着数字,那么 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/

相关文章:

java - 7u21 更新后弹出需要身份验证的窗口

cocoa - 无法从 Cocoa 中的 EXIF 获取创建图像的日期

java - 在 Java 中按日期范围组织对象

java - JMD 的替代方案

java - 如何初始化SortedMap?

java - 如何在 Android 中舍入十进制数

c# - 导入MySQL时格式化数据表日期列

PHP 将 SQL 日期转换为显示为数字字符串的不同格式

javascript - Date.parse 意外返回字符串

java - 根据字段是否存在,使用 Spring 从 MongoDB 投影 boolean 值