到目前为止,所有给出的答案都说你必须使用异常捕获,但是
有方法可以完全避免异常。我演示了两种方法,一种是使用内置的
SimpleDateFormat
-API,另一种是使用我的库
Time4J。
SimpleDateFormat
private static final List<SimpleDateFormat> SDF_FORMATS;
static {
String[] formats =
{
"yyyy-MM-dd'T'HH:mm:ss.SSSX",
"yyyy-MM-dd'T'HH:mm:ss.SSS-HH:mm",
"EEE MMM dd HH:mm:ss Z yyyy"
};
SDF_FORMATS =
Arrays.stream(formats)
.map(pattern -> new SimpleDateFormat(pattern, Locale.ENGLISH))
.collect(Collectors.toList());
}
public static java.util.Date parse(String input) {
for (SimpleDateFormat sdf : SDF_FORMATS) {
ParsePosition pos = new ParsePosition(0);
java.util.Date d = sdf.parse(input, pos);
if (pos.getErrorIndex() == -1) {
return d;
}
}
return null;
}
相对于try-catch代码,这段代码虽然表现不是非常抢眼,但已经有明显的性能提升。但需要注意的是,这个代码不是线程安全的。在多线程环境中使用时,你必须要么始终实例化一个新的SimpleDateFormat
,或者尝试使用ThreadLocal
来最小化这样的实例化。
Time4J
private static final MultiFormatParser<Moment> MULTI_FORMAT_PARSER;
static {
String[] formats =
{
"yyyy-MM-dd'T'HH:mm:ss.SSSX",
"yyyy-MM-dd'T'HH:mm:ss.SSS-HH:mm",
"EEE MMM dd HH:mm:ss Z yyyy"
};
List<ChronoFormatter<Moment>> formatters =
Arrays.stream(formats)
.map(pattern ->
ChronoFormatter.ofMomentPattern(
pattern,
PatternType.CLDR,
Locale.ENGLISH,
Timezone.ofSystem().getID()))
.collect(Collectors.toList());
MULTI_FORMAT_PARSER = MultiFormatParser.of(formatters);
}
public static java.util.Date parse(String input) {
ParseLog plog = new ParseLog();
Moment m = MULTI_FORMAT_PARSER.parse(input, plog);
if (plog.isError()) {
return null;
} else {
return TemporalType.JAVA_UTIL_DATE.from(m);
}
}
这是目前解析多种格式最快的方法。您可以自己试试(也可以使用3.x版本行,在Java-6或Android上使用Time4J,但需要在静态初始化程序中调整Java-8-streaming代码)。性能方面的改进非常大。而且代码也是线程安全的。
关于您的格式模式的一般说明:
- 我担心看到模式“yyyy-MM-dd'T'HH:mm:ss.SSS-hh:mm”,因为“h”代表12小时制钟表(所以缺少AM / PM!)。
- 我还担心看到模式“yyyy-MM-dd'T'HH:mm:ss.SSS'Z'”,因为在输入中转义文本“Z”是错误的,除非您在
SimpleDateFormat 实例上明确设置GMT-Zone(零偏移量)。背景:ISO-8601定义了这种模式,并始终将偏移UTC + 00:00分配给文本“Z”。通过转义,您将获得基于错误计算的结果(没有异常或警告)。
try
块可能抛出的ParseException
,没有其他异常,因此没有任何目的。根据dateString
来源的不同,可能会出现NullPointerException
。 - Andy Turnercatch
或finally
,那么您也不需要或希望try
。据我所知,catch
块通常存在于要捕获(特定的)异常的情况下。 - John BollingerParseException
。然后,如果抛出了RuntimeException
,那么它将被传播;并且编译器保证除了ParseException
之外不会抛出任何已检查的异常。因此,这只是以一种复杂的方式获得基本相同的行为。 - Andy Turner