![](/img/trans.png)
[英]NumberFormatException while parsing date with SimpleDateFormat.parse()
[英]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.