在我的程序中,在执行SimpleDataFormat.parse时,会间歇性地出现parseexception

bejyjqdl  于 2021-06-24  发布在  Storm
关注(0)|答案(2)|浏览(307)

在我的程序中,我会间歇性地 ParseException 在做的时候 SimpleDateFormat.parse .
我已经编写了一个apachestormbolt,我正在解析输入日期 "2018-02-26 18:13:32 UTC" .
并非每个输入日期都会引发此异常。另外,我在错误日志中打印了输入日期。从视觉上看,输入日期格式没有问题。
但我有一个 ParseException 对于间歇输入。
我怀疑是因为它是并发环境。
以下是代码段:

utcDateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss 'UTC'");
kyks70gy

kyks70gy1#

SimpleDateFormat 不是线程安全的,你真的可以得到一个 ParseException 在并发环境中。
详见此处。
对于Java8,您可以使用 DateTimeFormatter 这是线程安全的。

cgvd09ve

cgvd09ve2#

我怀疑是因为它是并发环境。
实际上,这是最可能的原因,因为 SimpleDateFormat 不是线程安全的。请在此处查看问题分析和解决方法:https://www.javaspecialists.eu/archive/issue172.html
除此之外,“utc”是一个重要的信息(它表明,好吧,日期是在utc中),所以你不能把它当作一个文字(在引号内)。您创建的格式化程序忽略了日期的utc格式(因为在内部引号中它被视为“some text”,而不是“it's in utc”),所以它实际上使用的是jvm默认时区(不一定是utc)。
要正确分析utc,必须使用 z 图案:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
Date date = sdf.parse("2018-02-26 18:13:32 UTC");

但如果您使用的是java 8或更高版本,只需使用新的date api:

DateTimeFormatter fmt = new DateTimeFormatterBuilder()
    // parse date and time
    .appendPattern("yyyy-MM-dd HH:mm:ss ")
    // parse UTC
    .appendOffset("+HH:MM", "UTC")
    // create the formatter
    .toFormatter();
OffsetDateTime odt = OffsetDateTime.parse("2018-02-26 18:13:32 UTC", fmt);

一开始看起来更复杂,但是这个新的api提供了很多不同的日期时间类型和更多的选项来解析和格式化它们。
更重要的是:它是线程安全的。

更新:

如评论中所建议的,您还可以执行以下操作:

DateTimeFormatter fmt  = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss zzz");
ZonedDateTime zdt = ZonedDateTime.parse("2018-02-26 18:13:32 UTC", fmt);

如果你还需要 java.util.Date ,很容易转换:

Date javaUtilDate = Date.from(zdt.toInstant());

这个 OffsetDateTime 类也有一个 toInstant() 方法,因此两者都可以转换为 Date .

相关问题