Java 8 LocalDateTime正在解析无效的日期时间

8ftvxx2r  于 2023-06-20  发布在  Java
关注(0)|答案(5)|浏览(120)

我想在客户端验证日期时间,所以我写了下面的代码。但是,我没有得到一个异常,而是得到了一个2月31日日期字符串的正确日期时间对象,这显然是一个无效的日期。

public class Test {

    public static void main(String[] args) {
        String dateFormat = "HH:mm:ss MM/dd/yyyy";
        String dateString = "11:30:59 02/31/2015";
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(dateFormat, Locale.US);
        try {
            LocalDateTime date = LocalDateTime.parse(dateString, dateTimeFormatter);
            System.out.println(date);
        } catch (Exception e) {
            // Throw invalid date message
        }
    }
}
    • 输出**:2015 - 02 - 28T11:30:59

有人知道为什么LocalDateTime解析这个日期时间而不是抛出异常吗?

tjvv9vkg

tjvv9vkg1#

你只需要一个严格的ResolverStyle
解析文本字符串分两个阶段进行。阶段1是根据添加到构建器的字段进行基本文本解析。阶段2将解析的字段-值对解析为日期和/或时间对象。此样式用于控制阶段2(解析)的发生方式。
示例代码-其中withResolverStyle(ResolverStyle.STRICT)是重要的更改,沿着使用uuuu而不是yyyy(其中uuuu是“year”,“yyyy”是“year of era”,因此不明确):

import java.time.*;
import java.time.format.*;
import java.util.*;

public class Test {

    public static void main(String[] args) {
        String dateFormat = "HH:mm:ss MM/dd/uuuu";
        String dateString = "11:30:59 02/31/2015";
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter
            .ofPattern(dateFormat, Locale.US)
            .withResolverStyle(ResolverStyle.STRICT);
        try {
            LocalDateTime date = LocalDateTime.parse(dateString, dateTimeFormatter);
            System.out.println(date);
        } catch (DateTimeParseException e) {
            // Throw invalid date message
            System.out.println("Exception was thrown");
        }
    }
}
aiazj4mn

aiazj4mn2#

Java 8 DateTimeFormatter使用yyyy表示YEAR_OF_ERA,使用uuuu表示YEAR。您需要修改模式字符串,如下所示:

String dateFormat = "HH:mm:ss MM/dd/uuuu";

DateTimeFormatter默认使用SMART冲突解决程序样式,但您希望它使用STRICT冲突解决程序样式。修改dateTimeFormatter初始化代码如下:

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(dateFormat, Locale.US)
                                                       .withResolverStyle(ResolverStyle.STRICT);
klr1opcd

klr1opcd3#

它不是四舍五入。二月从来没有31天,并且不可能使用验证日期/时间对象来表示不存在的一天。
因此,它接受无效的输入,并为您提供正确日期(该年2月的最后一个日期)的最佳近似值。
SimpleDateFormat继承自DateFormat,它有一个setLenient(boolean value)方法。我预计如果在解析之前调用setLenient(true),它可能会抱怨更多,如javadoc中详细说明的那样。

2vuwiymt

2vuwiymt4#

try {
    SimpleDateFormat df = new java.text.SimpleDateFormat("HH:mm:ss MM/dd/yyyy");
    df.setLenient(false);
    System.out.println(df.parse("11:30:59 02/29/2015"));
} catch (java.text.ParseException e) {
  System.out.println(e);
}

我发现了一个解决方案,通过DateFormat.setLenient(boolean)将date识别为有效日期。如果你试图解析任何无效的日期,它将抛出解析异常。

编辑:

Java 8,但如果一个月不在112之间,如果一天超过32,则会引发异常。完全不管用。但一个月的工作。

try {
TemporalAccessor ta = DateTimeFormatter.ofPattern("HH:mm:ss MM/dd/yyyy").parse("11:30:59 02/32/2015");
} catch (Exception e) {
System.out.println(e);
}

输出:

java.time.format.DateTimeParseException: Text '11:30:59 02/32/2015' could not be
 parsed: Invalid value for DayOfMonth (valid values 1 - 28/31): 32
wrrgggsh

wrrgggsh5#

parse只会在传入的String包含无效字符、天数超过31或月份超过12时抛出错误。
例如,如果您将代码修改为:

String dateString = "11:30:59 0zz2/31/2015";

一个异常将被抛出,这是由于给定日期内的无效'zz'字符引起的。至于为什么它的'四舍五入'的日期可以这么说,我不知道。
来源:https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html#parse-java.lang.CharSequence-

相关问题