【问题标题】:Java - validate that a given string represents a Date, i.e. "YYYY-MM-DD"?Java - 验证给定字符串是否代表日期,即“YYYY-MM-DD”?
【发布时间】:2014-01-10 21:30:13
【问题描述】:

用户给了我一个字符串,它应该代表过期日期,格式为“yyyy-mm-dd”。

我想验证它是否是一个日期,我就是这样做的:

try { 
    DateFormat df = new SimpleDateFormat("yyyy-mm-dd");
    System.out.println("Validating " + date + " as date");
    df.parse(date);
} 
catch (ParseException ex) { 
    // not yyyy-mm-dd date.
    System.out.println(": Bad");
    out.println(date + " cannot be parsed as a date. format: yyyy-mm-dd.");
    return;
}

如果用户给我"2014-02-02gy."

然后打印:"Validating 2014-02-02gy. as date"

即没有抛出异常。

为什么?以及如何验证日期?提前致谢。

编辑:使用正则表达式作为评论者建议之一:

if (!date.matches("\\d{4}-\\d{2}-\\d{2}")  {
    out.println("Not a date"); 
}

【问题讨论】:

  • 如果它遵循严格的格式(yyyy-mm-dd),我想你可以使用正则表达式来做一个快速的有效性测试。
  • 请注意,月份是M
  • 你可以使用正则表达式:"2014-02-02".matches("\\d{4}-\\d{2}-\\d{2}"),但这也适用于"2013-31-31"
  • 如果你能解析出一个明确的日期,你为什么要关心是否有额外的垃圾?
  • @Jaxo 我不确定 - 但 不在乎 ;-)

标签: java validation date datetime


【解决方案1】:

你总是可以用一种格式来反转解析,看看你最终得到的是不是你开始的。

DateFormat df = new SimpleDateFormat("yyyy-mm-dd");
String after = df.format(df.parse(date));
if (after.equals(date)) {
    // validated
}       

【讨论】:

    【解决方案2】:

    来自DateFormat.parse的文档

     * Parses text from the beginning of the given string to produce a date.
     * The method may not use the entire text of the given string.
     * <p>
     * See the {@link #parse(String, ParsePosition)} method for more information
     * on date parsing.
     *
     * @param source A <code>String</code> whose beginning should be parsed.
     * @return A <code>Date</code> parsed from the string.
     * @exception ParseException if the beginning of the specified string
     *            cannot be parsed.
    

    “如果无法解析指定字符串的开头。” - 它从头开始解析,直到获得所需的日期。因此,gy 已从您展示的示例中删除。

    修复:

    String date = "2014-02-02gy";
    try { 
        DateFormat df = new SimpleDateFormat("yyyy-mm-dd");
        System.out.println("Validating " + date + " as date");
        Date dateObject = df.parse(date);
        if(!df.format(dateObject).equals(date))
            throw new ParseException(date, 0);
    } catch (ParseException ex) { // not yyyy-mm-dd date.
        System.out.println(": Bad");
        System.out.println(date + " cannot be parsed as a date. format: yyyy-mm-dd.");
        return;
    }
    

    【讨论】:

      【解决方案3】:

      注意SimpleDateFormat#parse(string) 的javadoc,上面写着

      该方法可能不会使用给定字符串的整个文本。

      我不相信您可以通过这种方式验证String 末尾的字符。请注意,日期是有效的。你只是想检查一个字符串是否匹配某个模式。

      【讨论】:

      • 好的,相关评论。那么如何解决问题呢?这种行为是否受“set lenient”的影响?
      • @user2864740 看起来不像。不是SimpleDateFormat
      • @Nadrendion 我的意思是,将 lenient 标志设置为 false 并不会改变尾随字符被忽略的事实。
      • 如果您想使用日期,请尝试使用 jodatime 库。
      【解决方案4】:

      如果您不致力于使用 Java 标准库,请查看Joda-Time。该库比标准 Java Dates 发展得多。您的案例的代码变得如此简单和干净:

      import org.joda.time.format.DateTimeFormat;
      import org.joda.time.format.DateTimeFormatter;
      ...
      try {
        DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
        System.out.println("Validating " + date + " as date");
        formatter.parseDateTime(date);
      } catch (IllegalArgumentException e) {
        System.out.println(": Bad");
        System.out.println(date + " cannot be parsed as a date. format: yyyy-mm-dd.");
        return;
      }
      ...
      

      另一方面,如果您必须坚持使用标准 Java,我会选择 ns47731'sChris Gerken's 解决方案(大致相同,我更喜欢 Chris,但这是个人喜好)。

      【讨论】:

        【解决方案5】:

        我使用以下正则表达式来验证日期:

        if(!date.matches("\\d{4}-\\d{2}-\\d{2}")  {
              out.println("Not a date"); 
         }
        

        感谢所有评论或回答的人:)

        【讨论】:

        • 注意这一点,因为它允许像“2012-13-01”这样的日期,实际上将转换为“2013-01-01”
        • @mardavi 我知道这并不完美,但是用户如何进入这是版主,所以我没有进行严格的检查
        【解决方案6】:

        由于 DateFormat 奇怪地只匹配字符串的开头(对我来说似乎是一个错误,但它已记录在案,太好了..),我会明确添加一个结束分隔符,像这样

            DateFormat df = new SimpleDateFormat("yyyy-mm-dd,");
            String date = "2014-02-02,";
            System.out.println("Validating " + date  + " as date");
            df.parse(date);
        

        【讨论】:

          猜你喜欢
          • 2013-07-06
          • 1970-01-01
          • 2015-09-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-19
          • 2011-02-12
          相关资源
          最近更新 更多