格式化和解析相同的日期提供不同的结果

Format and parsing same date provides different result

有人能告诉我为什么控制台上显示“10/09/2022”吗?

String sFecha = "10/21/2021";
try {
   SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
   System.out.println(sdf.format(sdf.parse(sFecha)));
} catch (java.text.ParseException e) {
   //Expected execution
}

注意:输入字符串是故意错误的 - 我期待异常!

你的格式是day/month/year。 21 不是一个有效的月份,似乎减去 12 得到一个有效的。

当您执行 sdf.parse() 时,您将文本转换为日期:

10 -> days
21 -> month
2021 -> year

并将 21 作为月份转换为 9(因为 21 % 12 = 9)。

使用 setLenient(false) 它将抛出异常:

With lenient parsing, the parser may use heuristics to interpret inputs that do not precisely match this object's format. With strict parsing, inputs must match this object's format.

java.time

java.util 日期时间 API 及其格式 API、SimpleDateFormat 已过时且容易出错。建议完全停止使用它们并切换到 modern Date-Time API*.

您在代码中观察到的问题是您在 SimpleDateFormat 中遇到的奇怪问题之一。 SimpleDateFormat 并没有因为格式错误而抛出异常,而是尝试错误地解析日期字符串。

解决方案使用 java.time,现代日期时间 API:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

public class Main {
    public static void main(String[] args) {
        String sFecha = "10/21/2021";
        try {
            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd/MM/yyyy");
            LocalDate date = LocalDate.parse(sFecha, dtf);
            System.out.println(date);
        } catch (DateTimeParseException e) {
            System.out.println("A problem occured while parsing the date string.");
            // ...Handle the exception
        }
    }
}

输出:

A problem occured while parsing the date string.

现在,将格式更改为MM/dd/yyyy,您将看到日期字符串将被成功解析。

Trail: Date Time.

了解有关现代日期时间 API 的更多信息

如果您想使用 SimpleDateFormat:

false传递给默认设置为trueSimpleDateFormat#setLenient

演示:

import java.text.SimpleDateFormat;

public class Main {
    public static void main(String[] args) {
        String sFecha = "10/21/2021";
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
            sdf.setLenient(false);
            System.out.println(sdf.format(sdf.parse(sFecha)));
        } catch (java.text.ParseException e) {
            System.out.println("A problem occured while parsing the date string.");
            // ...Handle the exception
        }
    }
}

输出:

A problem occured while parsing the date string.

* 如果您正在为 Android 项目工作,并且您的 Android API 水平仍然不符合 Java-8,请检查Java 8+ APIs available through desugaring. Note that Android 8.0 Oreo already provides support for java.time