我看过下面的代码,但我对这里正则表达式的使用感到困惑。这个checkDateSanity方法的要求是:
The DATE format is dd.MM.yyyy. (WARNING: the DATE must exist!!)
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;
}
我做了一些随机测试,无论有没有正则表达式都没有任何区别。是否有更深层的原因需要在这里进行正则表达式检查?想要降低计算成本?如果是这样的话,真的值得吗?
最佳答案
定义“有效”。
例如,正则表达式允许第 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
WILL 使用具有模式 dd.MM.yyyy
的 .setLenient(false)
SDF 进行解析,并被解释为 99 年的 1 月 1 日,即罗马帝国时期的某个时间(不像王子之歌)。
仅出于这个目的,该正则表达式就非常有用;如果传递了 2 位数字的年份,您可以使用正则表达式来出错,因为 SDF 无法拒绝此类输入。
因此,这是真正的建议!
那些旧的日期 API 非常糟糕。他们很糟糕。不要使用它们。更新您的 IDE,将 SimpleDateFormat
标记为非法。这是 java time 包,它正是你想要的。请注意,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
,这会强制您只能使用 2 位数字;它们都被解释为 20xx。 (99 年 1 月 1 日为 2099 年 1 月 1 日)。
关于java - 除了 SimpleDateFormat.parse 之外,是否还需要使用 Regex 来检查日期完整性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65755554/