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,它力求尽可能好地避免内部异常(不是在所有情况下,而是在大多数情况下没有异常)


这段代码清楚地展示了另一种设计的可能性。我认为,java的选择设计。如果用大量错误数据批量处理海量数据,时间< /代码>是潜在的瓶颈。

为什么不使用正则表达式?@丹尼尔,因为它不清楚,需要额外的编码工作(和测试)。我的问题更像是“是否有一些隐藏的JDK库我不知道,如果给定
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}]