在我的程序中,在执行SimpleDateFormat.parse时间歇性地获得ParseException

问题描述 投票:2回答:2

在我的计划中,我在做ParseException时间歇性地得到了SimpleDateFormat.parse

我写了一个apache storm bolt,因为我正在解析输入日期"2018-02-26 18:13:32 UTC"

每个输入日期都不会抛出此异常。此外,我已在错误日志中打印输入日期。视觉上输入日期格式没有问题。

但是我有ParseException用于间歇输入。

我怀疑是因为它是并发环境。

以下是代码段:

utcDateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss 'UTC'");
java date apache-storm simpledateformat
2个回答
4
投票

我怀疑是因为它是并发环境。

实际上,这是最可能的原因,因为SimpleDateFormat不是线程安全的。在这里查看问题的分析以及如何解决它:https://www.javaspecialists.eu/archive/Issue172.html

除此之外,“UTC”是一个重要的信息(它表明,日期是以UTC为单位),因此您不能将其视为文字(内部引号)。您创建的格式化程序忽略日期为UTC(因为内部引号将其视为“某些文本”,而不是“它在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或更高版本,请使用新的日期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提供了许多不同的日期时间类型以及更多解析和格式化它们的选项。

更重要的是:它的线程安全。

UPDATE:

正如评论中所建议的那样,您还可以:

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


1
投票

qazxsw poi不是线程安全的,你真的可以在并发环境中获得qazxsw poi。

有关详细信息,请参阅SimpleDateFormat

对于Java 8,您可以使用线程安全的qazxsw poi。

© www.soinside.com 2019 - 2024. All rights reserved.