Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple exceptions thrown parsing date string

Tags:

I am trying to parse a string into a date in the constructor of an object, which we will call Example. Here is the code

private static final SimpleDateFormat sdf = new SimpleDateFormat(
        "yyyy-MM-dd HH:mm:ss");

private long time;

public Example(String date) {
    try {
        this.time = sdf.parse(date).getTime();
    } catch (Exception e) {
        logger.log(Level.WARNING, "Exception while parsing date " + date, e);
    }
}

Now, I am creating these objects in a Tomcat instance (whether that makes any difference or not).

I get the following types of exceptions

Fri Jul 06 15:13:48 EDT 2012 WARNING: Exception while parsing date 2012-07-06 18:57:31
java.lang.NumberFormatException: For input string: ""
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
    at java.lang.Long.parseLong(Long.java:431)
    at java.lang.Long.parseLong(Long.java:468)
    at java.text.DigitList.getLong(DigitList.java:177)
    at java.text.DecimalFormat.parse(DecimalFormat.java:1297)
    at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1589)
    at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1311)
    at java.text.DateFormat.parse(DateFormat.java:335)
    at ...
Fri Jul 06 15:13:48 EDT 2012 WARNING: Exception while parsing date 2012-07-06 19:00:07
java.lang.NumberFormatException: multiple points
    at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1082)
    at java.lang.Double.parseDouble(Double.java:510)
    at java.text.DigitList.getDouble(DigitList.java:151)
    at java.text.DecimalFormat.parse(DecimalFormat.java:1302)
    at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1934)
    at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1311)
    at java.text.DateFormat.parse(DateFormat.java:335)
    at ...
Fri Jul 06 15:13:48 EDT 2012 WARNING: Exception while parsing date 2012-07-06 19:13:21
java.lang.ArrayIndexOutOfBoundsException: -1
    at java.text.DigitList.fitsIntoLong(DigitList.java:212)
    at java.text.DecimalFormat.parse(DecimalFormat.java:1295)
    at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1934)
    at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1311)
    at java.text.DateFormat.parse(DateFormat.java:335)
    at ...
Fri Jul 06 15:48:06 EDT 2012 WARNING: Exception while parsing last check string 2012-07-06 19:08:08
java.lang.NumberFormatException: For input string: ".200172E4.200172"
    at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1222)
    at java.lang.Double.parseDouble(Double.java:510)
    at java.text.DigitList.getDouble(DigitList.java:151)
    at java.text.DecimalFormat.parse(DecimalFormat.java:1302)
    at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1589)
    at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1311)
    at java.text.DateFormat.parse(DateFormat.java:335)
    at ...

So it fails for the dates

2012-07-06 18:57:31
2012-07-06 19:00:07
2012-07-06 19:13:21
2012-07-06 19:08:08

However, if I make a unit test I get the following values for time from these strings

1341615451000
1341615607000
1341616401000
1341616088000

So the SimpleDateFormat object does work... but not on the server? I have noticed that this issue occurs near the startup of the server, and then not later on, if that helps at all. Not really sure what to do next.

Using Tomcat 7.0 and Java 1.6 update 32.

like image 904
skynet Avatar asked Jul 06 '12 19:07

skynet


3 Answers

SimpleDateFormat is not thread safe, as explained https://www.palantir.com/2007/07/simpledateformat-is-not-thread-safe/ Sometimes, really strange or non-logical behaviors when using "static" objects comes from concurrency issues

To resolve such a case, use a new instance each time (It is better than synchronizing, as synchronization can raise a bottleneck issue)

like image 199
cporte Avatar answered Sep 28 '22 02:09

cporte


SimpleDateFormat is not thread-safe: see the Javadoc.

like image 39
user207421 Avatar answered Sep 28 '22 01:09

user207421


As of Java 8+, it might be better to prefer a java.time based solution.

The classes in java.time are thread safe.

You can achieve the equivalent date extraction like that:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

...

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

LocalDateTime date = LocalDateTime.parse(str, dockerDateFormatter);

and then query the fields you need from date.

More details in the JavaDoc for DateTimeFormatter and LocalDateTime.

Another TLDR resource with two ready-to-use examples.

like image 20
jopasserat Avatar answered Sep 28 '22 01:09

jopasserat