Java 除了SimpleDateFormat.parse之外,是否有必要使用正则表达式检查日期的完整性?

Java 除了SimpleDateFormat.parse之外,是否有必要使用正则表达式检查日期的完整性?,java,Java,我看过下面的代码,对这里正则表达式的用法感到困惑。此checkDateSanity方法的要求是: 日期格式为dd.MM.yyyy。(警告:日期必须存在!!) 我读过这篇关于类似主题的文章,答案只是使用 try { DateFormat df = new SimpleDateFormat(DATE_FORMAT); df.setLenient(false); df.parse(dateString);

我看过下面的代码,对这里正则表达式的用法感到困惑。此checkDateSanity方法的要求是:

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

我读过这篇关于类似主题的文章,答案只是使用

        try {
            DateFormat df = new SimpleDateFormat(DATE_FORMAT);
            df.setLenient(false);
            df.parse(dateString);
            return true;
        } catch (ParseException e) {
            return false;
        }
我做了一些随机测试,不管有没有,正则表达式都没有任何区别。有没有更深层的理由在这里检查正则表达式?想降低计算成本吗?如果是这样的话,它真的值得吗?

定义“有效”

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

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

将两者结合在一起可以让你得到最严格的要求,但它确实让人感到费解。接受
1-1-2020
是否存在特别严重的问题

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

仅就这一目的而言,正则表达式是非常有用的;如果超过了2位数的年份,您可以使用regexp来出错,因为SDF不能拒绝这种输入

因此,真正的建议! 那些过时的API太糟糕了。他们很烂。不要使用它们。更新IDE,将
simpleDataFormat
标记为非法。这是java时间包,它正是您想要的。请注意,SDF返回一个
java.util.Date
,它是一个说谎的说谎者:它表示时间上的一个瞬间,不需要表示日期。事实并非如此——这就是为什么所有的
.getYear()
etc方法都被弃用的原因

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
,它强制您只使用2位数字;它们都被解释为20xx。(1.1.99 is 2099-01-01)。

您必须询问编写代码的人。也许这是代码在被重构为使用
SimpleDateFormat.parse
之前如何工作的遗留问题。我看不出有任何理由使用
if
语句。我建议您不要使用
SimpleDateFormat
Date
。这些类设计得很糟糕,而且早已过时,其中前者尤其令人讨厌。而是使用
LocalDate
DateTimeFormatter
,两者都来自。不,那么就不需要正则表达式了。
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.