在JAVA中将无效字符串传递给SimpleDateFormat时引发异常



我有一个传入字符串,它应该是一个格式为"yyyyMMdd"的日期。(例如,今天的日期-20200507(但有时输入字符串可能是无效的格式,日期解析器应该给出一个异常(解析异常(,但它不是,除非它返回了一个日期对象。

字符串错误或字母数字如下时的示例代码:

class Demo {
public static void main(String args[]) throws Exception {
String inputString = "9450524Q";
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH);
System.out.println(formatter.parse(inputString));
}}

输出:

Tue Apr 04 00:00:00 IST 9454

来自SimpleDateFormat直接继承的DateFormat的JavaDoc:

默认情况下,解析是宽松的:如果输入不是该对象的格式化方法使用的形式,但仍然可以解析为日期,则解析成功。客户可以通过呼叫setLenient(false)来坚持严格遵守格式。

java.time

我建议您使用现代java日期和时间API java.time来进行日期工作。在特定情况下的优势包括,您需要的格式化程序已经内置,并且它确实抛出了您要求的异常。

为了演示,我使用了这种辅助方法:

public static void tryToParse(String dateString) {
try {
LocalDate date
= LocalDate.parse(dateString, DateTimeFormatter.BASIC_ISO_DATE);
System.out.println(dateString + " -> " + date);
} catch (DateTimeParseException dtpe) {
System.out.println(dateString + ": " + dtpe.getMessage());
}
}

尝试一下:

// Valid date
tryToParse("20200507");
// Invalid date value
tryToParse("20210229");
// Text after date
tryToParse("20200623Q");
// Example from question
tryToParse("9450524Q");

输出为:

20200507 -> 2020-05-07
20210229: Text '20210229' could not be parsed: Invalid date 'February 29' as '2021' is not a leap year
20200623Q: Text '20200623Q' could not be parsed, unparsed text found at index 8
9450524Q: Text '9450524Q' could not be parsed at index 6

也请享受精确而有用的异常消息。最后一种情况是:分析了9450年和52月,但由于4Q不是有效的两位数日期,所以抛出了异常(在验证52是否是有效的月号之前(。

您的代码中发生了什么

SimpleDateFormat类是一个臭名昭著的麻烦制造者。你已经发现了它的一个核心设计问题,但肯定不是唯一的问题。它所做的是:它解析了四位数的年份9450和两位数的月份52。一年有12个月,但标准设置的SimpleDateFormat并不在乎。它将其中48个月转换为4年,并在4年后的第4个月结束。最后,4被解析为月中的某一天。忽略文本的其余部分Q

在我看来,你的例子展示了SimpleDateFormat:的三个缺陷

  1. 对于标准设置,它是宽松,它接受无效的月份号
  2. 当被要求解析两个数字而只找到一个数字时,它会使用这一个数字而不报告错误
  3. 在解析文本之后出现不可解析文本的情况下,它也不会报告任何错误

链接

  • Oracle教程:日期时间,解释如何使用java.Time
  • 相关问题:SimpleDateFormat给出错误的日期而不是错误
    • 现代答案
  • 当str=2011/12/12aaaaaa时,SimpleDateFormat解析(字符串str(不会引发异常?
    • 现代答案

相关内容

  • 没有找到相关文章

最新更新