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