我想检查一下String
是否可转换为ZonedDateTime
String datetime = "2018-01-11T21:32:10.876+02:00"; // valid
String badDateTime = "blah blah"; //not valid
我考虑过用this regex检查一下,但由于私人原因,这对我来说不是一个相关的解决方案。
我还考虑过以这种方式使用try..catch
public void testing() {
String datetime = "2018-01-11T21:32:10.876+02:00";
System.out.println(isDateTime("no")); // false
System.out.println(isDateTime(datetime)); // true
}
private boolean isDateTime(String str){
boolean checkDateTimeString;
try {
ZonedDateTime.parse(str);
checkDateTimeString = true;
} catch (DateTimeParseException e){
checkDateTimeString = false;
}
return checkDateTimeString;
}
但是使用例外作为返回值是不好的做法,而且性能成本很高。
有没有其他简单而好的方法来做那件事?
答案 0 :(得分:2)
如果查看ZonedDateTime.parse
方法实现,您会发现该方法定义如下:
public static ZonedDateTime parse(CharSequence text) {
return parse(text, DateTimeFormatter.ISO_ZONED_DATE_TIME);
}
public static ZonedDateTime parse(CharSequence text, DateTimeFormatter formatter) {
Objects.requireNonNull(formatter, "formatter");
return formatter.parse(text, ZonedDateTime::from);
}
如果你也看DateTimeFormatter
,你会发现一个名为parseUnresolved
的方法。您可以按如下方式使用它:
DateTimeFormatter.ISO_ZONED_DATE_TIME.parseUnresolved(str, new ParsePosition(0));
传递的字符串将被解析但未解析。然后,您可以查看parseResolved0
实现并执行实际解析而不会抛出异常。您将不得不使用方法返回值。
您需要的方法如下:
public TemporalAccessor parse(final CharSequence text) {
ParsePosition pos = new ParsePosition(0);
TemporalAccessor temporalAccessor = DateTimeFormatter.ISO_ZONED_DATE_TIME.parseUnresolved(text, pos);
if (temporalAccessor == null || pos.getErrorIndex() >= 0 || pos.getIndex() < text.length()) {
return null;
}
return temporalAccessor;
}
请注意,返回的TemporalAccessor
将无法解析。我需要更深入地查看代码才能找到它的含义。
最后,如果你想检查一个字符串是否可以被解析为ZonedDateTime
而没有例外,你只需要检查返回值:
parse("2018-01-11T21:32:10.876+02:00"); //return ZonedDateTime instance
parse("blah blah"); //return null
修改强>
由于无法使用返回的Parsed
,因此编写解析方法是“错误的”(除非TemporalAccessor公开的方法对您有用)。因此,检查有效性的方法会更正确:
public boolean isParseableAsZonedDateTime(final CharSequence text) {
ParsePosition pos = new ParsePosition(0);
TemporalAccessor temporalAccessor = DateTimeFormatter.ISO_ZONED_DATE_TIME.parseUnresolved(text, pos);
if (temporalAccessor == null || pos.getErrorIndex() >= 0 || pos.getIndex() < text.length()) {
return false;
}
return true;
}
答案 1 :(得分:1)
使用异常作为返回值是不好的做法,而且性能成本很高。
这是一个好点,值得寻找替代方案,但在某些情况下,这只是提供的API。通常,对于解析,您确实需要异常,因为解析失败是例外情况 - 您希望解析该值,并且只需考虑它没有的可能性。
在这种情况下,我只是抓住你正在做的例外。