问题描述
我正在为某些遗留代码编写测试,以验证用户的出生日期。我在课堂上遇到以下方法。我的疑问是是否需要在try块中使用if语句。根据我的理解,如果解析函数成功返回了LocalDate对象,则date.toString()应始终等于输入dobstr,并且无需进行其他检查。我有什么想念的吗?我想不出我们需要这项额外检查的情况。请帮忙。谢谢!
js,hbs
这是我在DateTimeFormatter.ISO_DATE的源代码中找到的
private LocalDate format(String dobStr) throws Exception {
LocalDate date = null;
try {
date = LocalDate.parse(dobStr,DateTimeFormatter.ISO_DATE);
if (!dobStr.equals(date.toString())) {
throw new DateTimeParseException("some message");
}
}
catch (DateTimeParseException ex) {
throw ex;
}
return date;
}
解决方法
我看到进行toString()
检查的唯一原因是为了避免宽大的问题:解析器可能是宽大的,并试图解释错误的值(例如:2020-12-32可以解释为2021-01-01)。
- DateFormat allows the parser to be lenient
- The same behaviour is offered by DateTimeFormatter,默认值为
ResolverStyle.SMART
。
如果要删除它,则应检查DateTimeFormatter.ISO_DATE
是否默认为ResolverStyle.STRICT
。假设默认情况下不是STRICT,则您的代码可能是:
private LocalDate format(String dobStr) throws Exception {
return LocalDate.parse(dobStr,DateTimeFormatter.ISO_DATE.withResolverStyle(ResolverStyle.STRICT));
}
,
TL; DR:检查有所作为
如果该字符串包含不需要的偏移ID,您仍然可以使用DateTimeFormatter.ISO_DATE
对其进行解析。但是由于LocalDate
不能有偏移量(这就是名称中的 local 的含义),所以toString()
的结果将永远没有该偏移量ID,因此字符串将不会平等。
DateTimeFormatter.ISO_DATE
在日期之后接受可选的偏移ID。因此,如果您要解析2020-08-12z
或2020-08-12+01:02:03
,则将引发自定义异常。除了细节外,DateTimeParseException
没有与单个字符串参数匹配的构造函数,因此代码无法编译。我认为这是源于原始代码的草率复制粘贴。
演示:
String dobStr = "2020-08-12+01:02:03";
LocalDate date = LocalDate.parse(dobStr,DateTimeFormatter.ISO_DATE);
String asStringAgain = date.toString();
System.out.format("Original string: %s; result of toString(): %s; equal? %s%n",dobStr,asStringAgain,dobStr.equals(asStringAgain));
输出为:
原始字符串:2020-08-12 + 01:02:03; toString()的结果: 2020-08-12;等于?错误
如何取消支票
除非在不需要的偏移量的情况下需要自定义异常,否则该方法的编写可能更加简单:
private LocalDate format(String dobStr) throws Exception {
return LocalDate.parse(dobStr,DateTimeFormatter.ISO_LOCAL_DATE);
}
DateTimeFormatter.ISO_LOCAL_DATE
不接受字符串中的任何偏移量。而且它就像DateTimeFormatter.ISO_DATE
一样严格,因此我们知道toString()
会再次创建相同的字符串。
此外,您可以声明方法static
,并且可以省去throws Exception
,因为DateTimeParseException
是未经检查的异常。