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



在我的程序中,我在做SimpleDateFormat.parse时断断续续地ParseException

我写了一个阿帕奇风暴螺栓,因为我正在解析输入日期"2018-02-26 18:13:32 UTC"

不会为每个输入日期引发此异常。另外,我已经在错误日志中打印了输入日期。从视觉上看,输入日期格式没有问题。

但我有间歇性输入的ParseException

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

以下是代码片段:

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

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

实际上,这是最可能的原因,因为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 提供了许多不同的日期时间类型以及更多用于解析和格式化它们的选项。

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

更新:

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

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

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

详情请看这里。

对于Java 8,您可以使用线程安全的DateTimeFormatter

相关内容

最新更新