简体   繁体   English

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

[英]In my program am getting intermittently ParseException while doing SimpleDateFormat.parse

In my program I am getting intermittently a ParseException while doing SimpleDateFormat.parse . 在我的程序中,执行SimpleDateFormat.parse时间歇性地获取ParseException

I have written one apache storm bolt, in that I am parsing the input date "2018-02-26 18:13:32 UTC" . 我写了一个Apache风暴螺栓,因为我正在解析输入日期"2018-02-26 18:13:32 UTC"

This exception is not thrown for every input date. 并非在每个输入日期都抛出此异常。 Also, I have printed the input date in error log. 另外,我已经在错误日志中打印了输入日期。 Visually there are no issues with input date format. 在视觉上,输入日期格式没有问题。

But I've got the ParseException for intermittent inputs. 但是我有用于间歇输入的ParseException

I doubt is that because it is concurrent environment. 我怀疑是因为它是并发环境。

Following is the code snippet: 以下是代码段:

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

I doubt is that because it is concurrent environment. 我怀疑是因为它是并发环境。

Actually, that's the most probable cause, because SimpleDateFormat is not thread safe. 实际上,这是最可能的原因,因为SimpleDateFormat不是线程安全的。 Check here an analysis of the problem and how to fix it: https://www.javaspecialists.eu/archive/Issue172.html 在此处检查问题分析以及如何解决问题: https//www.javaspecialists.eu/archive/Issue172.html

Apart from that, "UTC" is an important information (it indicates that, well, the date is in UTC), so you can't treat it as a literal (inside quotes). 除此之外,“ UTC”是重要信息(它表示日期以UTC为单位),因此您不能将其视为文字(在引号内)。 The formatter you created is ignoring that the date is in UTC (because inside quotes it's treated as "some text" , not as "it's in UTC" ), so it's actually using the JVM default timezone (which can't necessarily be UTC). 您创建的格式化程序会忽略日期为UTC(因为在引号内将其视为“某些文本” ,而不是“在UTC中” ),因此它实际上是使用JVM默认时区(不一定是UTC) 。

To correctly parse UTC , you must use the z pattern: 要正确解析UTC ,必须使用z模式:

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

But if you're using Java 8 or higher, just use the new date API: 但是,如果您使用的是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);

It seems more complicated at first, but this new API provides lots of different date-time types and much more options to parse and format them. 乍一看似乎比较复杂,但是这个新的API提供了许多不同的日期时间类型以及更多的选项来解析和格式化它们。

And more important: it's thread safe . 更重要的是: 它是线程安全的

UPDATE: 更新:

As suggested in the comments, you can also do: 如评论中所建议,您还可以执行以下操作:

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

If you still need to work with java.util.Date , it's easy to convert: 如果仍然需要使用java.util.Date ,则很容易进行转换:

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

The OffsetDateTime class also has a toInstant() method, so both can be converted to Date . OffsetDateTime类还具有toInstant()方法,因此两者都可以转换为Date

SimpleDateFormat is not threadsafe and you really can get a ParseException in the concurrent environment. SimpleDateFormat不是线程安全的,您实际上可以在并发环境中获得ParseException

See here for details. 有关详细信息,请参见此处

For Java 8 you can use DateTimeFormatter which is threadsafe. 对于Java 8,可以使用线程安全的DateTimeFormatter

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM