Using this code below, I noticed that sometimes the date gets formatted incorrecty. And to make it even more weird, sometimes timeStamp will have the right date, and timeStampCopy will have the wrong date, and visa versa.
public static Timestamp method(String date, DateFormat dateFormat) throws Exception {
// date is always "2017-02-17"
// original
GregorianCalendar gCal = new GregorianCalendar();
gCal.setTime(dateFormat.parse(date));
Timestamp timeStamp = new Timestamp(gCal.getTimeInMillis());
// copy
GregorianCalendar gCalCopy= new GregorianCalendar();
gCalCopy.setTime(dateFormat.parse(date));
Timestamp timeStampCopy = new Timestamp(gCalCopy.getTimeInMillis());
if (!timeStamp.toString().contains("2017-02-17"))
System.out.println(timeStamp.toString());
if (!timeStampCopy.toString().contains("2017-02-17"))
System.out.println(timeStampCopy.toString());
return timeStamp;
}
I'm not sure what could be causing it but I tried this using a Date object and am having the same issues. I thought it could be a parsing issue but since it's doing the same thing twice I'm not sure.
Below are some of the values that I'm getting:
timeStamp is: 2017-02-17 00:00:00.0
timeStampCopy is: 1700-02-17 00:00:00.0
You say that you are sharing the DateFormat
instance between threads.
According to the Javadoc:
Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.
Note that this refers to external synchronization of access to the DateFormat
instance, not the method. Making the method synchronized
would only fix this problem if there are no other uses of the DateFormat
instance.
You can either:
DateFormat
instance (it is worth adding an @GuardedBy
annotation to the variable, in order to document that you expect a lock to be held before using it);ThreadLocal<DateFormat>
(and initialize the shared variable appropriately), which ensures that each thread has its own copy of the DateFormat
.The latter approach has lower contention, because each thread can proceed independent of the others. It also means that you can't accidentally omit the synchronization.
But, there are better libraries for handling dates and times, which were designed with the hindsight of problems like DateFormat
's lack of thread safety. In Java 8, there is the java.time
API; for earlier versions of Java, there is Jodatime.