繁体   English   中英

除了 SimpleDateFormat.parse 之外,是否还需要使用 Regex 来检查日期完整性?

[英]Is it ncessary to use Regex to check date sanity in addition to SimpleDateFormat.parse?

我看过下面的代码,我对这里使用 Regex 感到困惑。 这个 checkDateSanity 方法的要求是:

DATE 格式为 dd.MM.yyyy。 (警告:日期必须存在!!)

   private boolean checkDateSanity(String dateString) {
    if (Pattern.matches("[0-3][0-9].[0-1][0-9].[0-9]{4}", dateString)) {
        try {
            DateFormat df = new SimpleDateFormat(DATE_FORMAT);
            df.setLenient(false);
            df.parse(dateString);
            return true;
        } catch (ParseException e) {
            return false;
        }
    }

    return false;
}

我已经阅读了有关类似主题的这篇文章How to sanity check a date in Java ,其中答案只是使用

        try {
            DateFormat df = new SimpleDateFormat(DATE_FORMAT);
            df.setLenient(false);
            df.parse(dateString);
            return true;
        } catch (ParseException e) {
            return false;
        }

我做了一些随机测试,无论有没有它,Regex 都没有任何区别。 有没有更深层次的理由让 Regex 在这里检查? 想降低计算成本? 如果是这样的话,真的值得吗?

定义“有效”。

例如,正则表达式允许在第 19 个月的第 39 天以及第 0 个月的第 0 天:根据它, 39-19-0000是有效日期,但1-1-2020不是(仅01-01-2020将是)。

SDF 是旧的 API ,您不应该使用(使用java.time ),但就这段代码而言,宽大已关闭,因此它不接受39-19-0000 ,尽管它会接受1-1-2020

将两者结合起来会让你得到最严格的要求,但它确实让人感到复杂。 接受1-1-2020是否有特别令人发指的问题?

但请注意这个巨大的问题:年份混乱。 1-1-99使用带有模式dd.MM.yyyy.setLenient(false) SDF 进行解析,并被解释为 99 年的 1 月 1 日,即罗马帝国时期的某个时候(不像王子歌)。

仅出于这个目的,该正则表达式就非常有用; 如果通过了 2 位数年份,您可以使用正则表达式出错,因为 SDF 不能拒绝这种输入。

因此,真正的建议!

那些旧的日期 API 非常糟糕。 他们很烂。 不要使用它们。 更新您的 IDE,将SimpleDateFormat标记为非法。 这是 java 时间 package,做你想做的事。 请注意,SDF 返回一个java.util.Date ,这是一个撒谎的骗子:它代表时间的瞬间并且没有代表日期的业务。 它真的没有 - 这就是所有各种.getYear()等方法都被弃用的原因。

LocalDate x = LocalDate.parse("01.01.1999", DateTimeFormatter.ofPattern("dd.MM.yyyy"));
System.out.println(x);
> 1999-01-01

// Awesome. It's an actual _DATE_ and not a timestamp where timezones
// can mess everything up.

LocalDate x = LocalDate.parse("01.01.99", DateTimeFormatter.ofPattern("dd.MM.yyyy"));
> Exception in thread "main" java.time.format.DateTimeParseException: Text '01.01.1999' could not be parsed

// perfect. it crashes, as it should.

LocalDate x = LocalDate.parse("1.1.1999", DateTimeFormatter.ofPattern("dd.MM.yyyy"));
> Exception in thread "main" java.time.format.DateTimeParseException: Text '01.01.1999' could not be parsed

// if you want `1.1.1999` to crash, well, you can.

LocalDate x = LocalDate.parse("1.1.1999", DateTimeFormatter.ofPattern("d.M.yyyy"));
System.out.println(x);
> 1999-01-01

// but you don't have to. with just `d`, 1 parses as 1, so does 01.

您也可以使用yy go ,这迫使您只使用 2 位数字; 它们都被解释为 20xx。 (1.1.99 是 2099-01-01)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM