I have declared a SimpleDateFormat object as a static field inside the constant file as follows,
Constants.java
public static final SimpleDateFormat GENERAL_TZ_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
and inside my class file my implementation like this.
String fDate = getTextValue(empNo, "firstDate");
if (null != fDate && !fDate.isEmpty()) {
try {
Date date = (Date)(Constants.GENERAL_TZ_FORMATTER).parse(fDate);
issue.setDate(date.getTime());
} catch (ParseException e) {
logUtil.error(LOG, e+ "date : " + date);
}
}
Error :
Exception while importing data. package name.SecureException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
My problem is, in some cases, this throws a NumberFormatException
(a very rare situation), so I've been wondering about that an I did a diagnosis, and most of them are explaining this case might happen due to that SimpleDateFormat is not thread-safe. If this is the case, I'm not clear how this code running in a multiple thread environment without using multiple threads, would it make the input to DateFormat.parse() an empty string?
Java's SimpleDateFormat is not thread-safe article
I have tried to solve this problem, but It's really hard to recreate this issue, I like to know your ideas about this and it will help me to find a better solution. Really appreciate your suggestions. Thank you.
Well, as the comment below your post already mentioned, you shouldn't use SimpleDateFormat
anyway.
You have probably stumbled upon such case where SimpleDateFormat
is troublesome. This is not the only reason, however. This Stackoverflow post explains why it is so troublesome. One of the reasons in that very same post mention SimpleDateFormat
not being thread-safe. Thread-safety is that when multiple processes act upon the formatter, that is, leverage the formatter to format a date, and that no incorrect, inaccurate or undefined results occur because of interference.
Your link to the article on Callicoder explains pretty well why SimpleDateFormat
cause trouble. The post mentions the same exception as you got:
java.lang.NumberFormatException: For input string: ""
In short, the threads interfere when they use the formatter, because the formatter is not synchronized. That means that the SimpleDateFormat
class does not enforce that one thread must wait until some other thread has finished with modifying its internal state. Three of the used classes are SimpleDateFormat
, DateFormat
and FieldPosition
.
Here's erroneous code in action.
java.time
You need to move to the newer Java 8 Date and Time API, available in the java.time
package. They're absolutely thread-safe because of their immutable nature. In your case, use java.time.format.DateTimeFormatter
:
public static final DateTimeFormatter GENERAL_TZ_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");
ZonedDateTime zdt = ZonedDateTime.parse(fDate, GENERAL_TZ_FORMATTER);
Instant instant = zdt.toInstant();
// Your setDate should really accept an Instant:
issue.setDate(instant);
// If that's REALLY not possible, then you can convert it to an integer
// value equal to the number of milliseconds since 1 January 1970, midnight
//issue.setDate(instant.toEpochMilli());