是否需要额外检查将字符串解析为 LocalDate 对象?
Is this additional check for parsing a string to LocalDate object necessary?
我正在为一些验证用户出生日期的遗留代码编写一些测试。我在class中遇到了下面的方法。我的疑问是 try 块中的 if 语句是否有必要。根据我的理解,如果解析函数 returns LocalDate 对象成功,那么 date.toString() 应该总是等于输入的 dobstr,并且不需要做额外的检查。我错过了什么吗?我想不出我们需要这种额外检查的任何情况。请帮忙。谢谢!
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;
}
这是我在 DateTimeFormatter.ISO_DATE
的源代码中找到的内容
public static final DateTimeFormatter ISO_DATE;
static {
ISO_DATE = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(ISO_LOCAL_DATE)
.optionalStart()
.appendOffsetId()
.toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
}
我能看到进行 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
没有匹配单个字符串参数的构造函数,因此代码无法编译。我认为这来自原始代码的草率copy-paste。
演示:
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));
输出为:
Original string: 2020-08-12+01:02:03; result of toString():
2020-08-12; equal? false
如何避免检查
除非您在不需要的偏移量的情况下需要自定义异常,否则该方法可能会写得更简单:
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
是一个未经检查的异常。
Link
我正在为一些验证用户出生日期的遗留代码编写一些测试。我在class中遇到了下面的方法。我的疑问是 try 块中的 if 语句是否有必要。根据我的理解,如果解析函数 returns LocalDate 对象成功,那么 date.toString() 应该总是等于输入的 dobstr,并且不需要做额外的检查。我错过了什么吗?我想不出我们需要这种额外检查的任何情况。请帮忙。谢谢!
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;
}
这是我在 DateTimeFormatter.ISO_DATE
的源代码中找到的内容public static final DateTimeFormatter ISO_DATE;
static {
ISO_DATE = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(ISO_LOCAL_DATE)
.optionalStart()
.appendOffsetId()
.toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
}
我能看到进行 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
没有匹配单个字符串参数的构造函数,因此代码无法编译。我认为这来自原始代码的草率copy-paste。
演示:
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));
输出为:
Original string: 2020-08-12+01:02:03; result of toString(): 2020-08-12; equal? false
如何避免检查
除非您在不需要的偏移量的情况下需要自定义异常,否则该方法可能会写得更简单:
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
是一个未经检查的异常。