简体   繁体   中英

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

In my program I am getting intermittently a ParseException while doing SimpleDateFormat.parse .

I have written one apache storm bolt, in that I am parsing the input date "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.

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. Check here an analysis of the problem and how to fix it: 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). 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).

To correctly parse UTC , you must use the z pattern:

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:

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.

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:

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

The OffsetDateTime class also has a toInstant() method, so both can be converted to Date .

SimpleDateFormat is not threadsafe and you really can get a ParseException in the concurrent environment.

See here for details.

For Java 8 you can use DateTimeFormatter which is threadsafe.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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