Java 是不是有一个好的 *strict* 日期解析器?

Posted

技术标签:

【中文标题】Java 是不是有一个好的 *strict* 日期解析器?【英文标题】:Is there a good *strict* date parser for Java?Java 是否有一个好的 *strict* 日期解析器? 【发布时间】:2010-10-04 02:57:32 【问题描述】:

有没有一个好的,strict Java 日期解析器?我可以访问 Joda-Time,但我还没有看到这个选项。我发现了“Is there a good date parser for Java”问题,虽然这是相关的,但它有点相反。虽然这个问题要求一个宽松的、更模糊的逻辑并且容易出现人为错误的解析器,但我想要一个严格的解析器。例如,对于 JodaTime(据我所知)和 simpleDateFormat,如果您的格式为“MM/dd/yyyy”:

解析这个:40/40/4353

这成为一个有效的日期。我想要一个知道 40 是无效月份和日期的解析器。 Java 中肯定存在这种实现吗?

【问题讨论】:

真的吗?年份固然有效,但至于日月,则不然。我必须看到这一点。如果我没记错的话,一年中会增加额外的月份,不是吗? 显然它是这样做的,它刚刚开始工作。但是,我没有能力结束这个问题。 Joda 时间最终将添加到 Java SE 中。这在首页 (java.sun.com/javase) 中有特色:JSR 310: A New Java Date/Time API。它说它是“..主要基于 Joda Time API”(today.java.net/pub/a/today/2008/09/18/…) @Metroid:关于关闭。我想将答案标记为已接受就足够了。 @Oscar:直到出现关闭(1),我才看到关闭链接。我的错。 【参考方案1】:

我没有看到 Joda 将其识别为有效日期。示例:

strict = org.joda.time.format.DateTimeFormat.forPattern("MM/dd/yyyy")
try 
    strict.parseDateTime('40/40/4353')
    assert false
 catch (org.joda.time.IllegalFieldValueException e) 
    assert 'Cannot parse "40/40/4353": Value 40 for monthOfYear must be in the range [1,12]' == e.message

据我所知,DateFormat 和 setLenient(false) 也没有。示例:

try 
    df = new java.text.SimpleDateFormat('MM/dd/yyyy')
    df.setLenient(false)
    df.parse('40/40/4353')
    assert false
 catch (java.text.ParseException e) 
    assert e.message =~ 'Unparseable'

希望这会有所帮助!

【讨论】:

您使用的是哪个版本的 JodaTime? 1.6 肯定会表现出这种行为。 这真的很奇怪。我有一个失败的测试,但由于某种原因它现在可以工作了,我得到了你提到的那个例外。很奇怪。那么,乔达时间到了! :) 很高兴了解 DateFormat(那里有很多东西很难找到您正在寻找的特定方法),但我喜欢 JodaTime,因为它与格式化程序实例没有任何同步问题. DateFormat 是一个真正的陷阱。【参考方案2】:

使用 DateFormat 进行严格验证的一个好方法是重新格式化解析的日期并检查与原始字符串的相等性:

String myDateString = "87/88/9999";
Date myDate = dateFormat.parse(myDateString);
if (!myDateString.equals(df.format(myDate)))
  throw new ParseException();

像魅力一样工作。

【讨论】:

如何处理,例如输入的日期或月份没有渲染添加的前导零? 如果渲染是由 Formatter 完成的(应该这样),那么绝对没有问题。如果您创建外部渲染格式化程序,您的里程可能会有所不同。【参考方案3】:

您可以使用apache.commons.validator.routines.DateValidator 来验证日期,如果您不想使用SimpleDateFormat

例子:

 public static Date validateDate(String value, String pattern) 
       DateValidator validator = new DateValidator();
       Date date = null;
           if (pattern!=null)     //Pattern is passed
               date = validator.validate(value, pattern);
            else 
               date = validator.validate(value);
           
       return date;
    

因此,如果返回 null,则表示日期无效,否则为有效日期。此方法是使用 SimpleDateFormat 的替代方法,因为您不必依赖抛出异常以确定它是否是有效日期。

【讨论】:

以上是关于Java 是不是有一个好的 *strict* 日期解析器?的主要内容,如果未能解决你的问题,请参考以下文章

Java中的日期选择

错误页面(400、401、403、500...)中是不是需要 Strict-Transport-Security?

Java:检查日期选择器是不是有值错误

java如何判断一个日期是不是是四个季末的日期

java中有没有判断日期格式是不是正确的函数

java中怎么做到判断输入的日期是不是合法