Java DateTimeFormatter是否可以在不捕获异常的情况下验证日期字符串?
考虑到(许多人)认为通过异常进行流控制是一种反模式,是否可以使用时态库(Java DateTimeFormatter是否可以在不捕获异常的情况下验证日期字符串?,java,exception-handling,temporal,Java,Exception Handling,Temporal,考虑到(许多人)认为通过异常进行流控制是一种反模式,是否可以使用时态库(java.time.*)验证字符串是否表示有效日期,而不捕获异常 考虑以下依赖于内部爆炸的代码: public static boolean isValidDateFormat(String date, DateTimeFormatter formatter) { try { formatter.parse(date); return true; } catch (DateTi
java.time.*
)验证字符串是否表示有效日期,而不捕获异常
考虑以下依赖于内部爆炸的代码:
public static boolean isValidDateFormat(String date, DateTimeFormatter formatter) {
try {
formatter.parse(date);
return true;
} catch (DateTimeParseException e) {
return false;
}
}
这可以在不捕获解析爆炸的情况下实现吗?是否有类似于
格式化程序.isValid(date)
的东西(即使它在内部爆炸-这将取决于“幕后”的JDK impl)。
出现异常,ParsePosition
-对象甚至不报告错误:
pp = new ParsePosition(0);
try {
TemporalAccessor t =
DateTimeFormatter.ofPattern("uuuu-MM-dd")
.withResolverStyle(ResolverStyle.STRICT)
.parse("2015-02-29", pp);
} catch (RuntimeException e) {
e.printStackTrace();
System.out.println("Error! " + pp);
// Error! java.text.ParsePosition[index=10,errorIndex=-1]
}
报告解释说:
此方法的操作与类似方法略有不同
在java.text.Format上使用ParsePosition。该类将返回错误
使用ParsePosition上的错误索引。相比之下,这种方法
如果发生错误,将抛出DateTimeParseException,其中
包含错误索引的异常。这种行为上的改变是不正确的
由于解析和解析的复杂性增加,这是必需的
此API中的日期/时间
以下示例尝试使用方法parseUnresolved
避免异常:
ParsePosition pp = new ParsePosition(0);
try {
TemporalAccessor t =
DateTimeFormatter.ofPattern("uuuu-MM-dd")
.withResolverStyle(ResolverStyle.STRICT)
.parseUnresolved("2015-02-29", pp);
System.out.println("Info! " + t + "/" + pp); // note, no error in pp here!
// Info! {DayOfMonth=29, MonthOfYear=2, Year=2015},null,null/java.text.ParsePosition[index=10,errorIndex=-1]
boolean leapyear = Year.from(t).isLeap();
MonthDay md = MonthDay.from(t);
if (!leapyear && md.getDayOfMonth() == 29 && md.getMonth().getValue() == 2) {
System.out.println("Error!"); // hand-made validation covering a special case
}
} catch (RuntimeException e) {
e.printStackTrace(); // does not happen for given input
}
这是毫无例外的,但是您必须自己编写验证代码,这会带来麻烦
我一直认为这种抛出异常以控制程序流的方法是不好的编码实践,因此我设计了自己的库Time4J,它力求尽可能好地避免内部异常(不是在所有情况下,而是在大多数情况下没有异常)
这段代码清楚地展示了另一种设计的可能性。我认为,
DateTimeFormatter
可以确定给定字符串是否有效”,我看到了。我不知道这个有效方法的存在。在JDK源代码中,您在使用调试器时找不到任何东西?也许可以看看jodatime,它实现了更多关于时间、时间格式和时间解析的功能。它使用较少的异常。
ParseLog plog = new ParseLog();
PlainDate date = ChronoFormatter.ofDatePattern("uuuu-MM-dd", PatternType.CLDR, Locale.ROOT).parse("2015-02-29", plog);
System.out.println(date); // null
System.out.println(plog.isError() + "/" + plog.getErrorMessage());
// true/Validation failed => DAY_OF_MONTH out of range: 29 [parsed={YEAR=2015, MONTH_AS_NUMBER=2, DAY_OF_MONTH=29}]