我想在客户端验证日期时间,所以我写了下面的代码。但是,我没有得到一个异常,而是得到了一个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
解析这个日期时间而不是抛出异常吗?
5条答案
按热度按时间tjvv9vkg1#
你只需要一个严格的
ResolverStyle
。解析文本字符串分两个阶段进行。阶段1是根据添加到构建器的字段进行基本文本解析。阶段2将解析的字段-值对解析为日期和/或时间对象。此样式用于控制阶段2(解析)的发生方式。
示例代码-其中
withResolverStyle(ResolverStyle.STRICT)
是重要的更改,沿着使用uuuu
而不是yyyy
(其中uuuu
是“year”,“yyyy”是“year of era”,因此不明确):aiazj4mn2#
Java 8 DateTimeFormatter使用yyyy表示YEAR_OF_ERA,使用uuuu表示YEAR。您需要修改模式字符串,如下所示:
DateTimeFormatter默认使用SMART冲突解决程序样式,但您希望它使用STRICT冲突解决程序样式。修改dateTimeFormatter初始化代码如下:
klr1opcd3#
它不是四舍五入。二月从来没有31天,并且不可能使用验证日期/时间对象来表示不存在的一天。
因此,它接受无效的输入,并为您提供正确日期(该年2月的最后一个日期)的最佳近似值。
SimpleDateFormat
继承自DateFormat
,它有一个setLenient(boolean value)
方法。我预计如果在解析之前调用setLenient(true)
,它可能会抱怨更多,如javadoc中详细说明的那样。2vuwiymt4#
我发现了一个解决方案,通过DateFormat.setLenient(boolean)将date识别为有效日期。如果你试图解析任何无效的日期,它将抛出解析异常。
编辑:
Java 8
,但如果一个月不在1
和12
之间,如果一天超过32
,则会引发异常。完全不管用。但一个月的工作。输出:
wrrgggsh5#
parse只会在传入的String包含无效字符、天数超过31或月份超过12时抛出错误。
例如,如果您将代码修改为:
一个异常将被抛出,这是由于给定日期内的无效'zz'字符引起的。至于为什么它的'四舍五入'的日期可以这么说,我不知道。
来源:https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html#parse-java.lang.CharSequence-