Had a funny issue with java Dates today which had me tearing my hair out: I was sending a java.sql.Date
from one machine to another, via RMI and then storing it into the database, but the date being stored was incorrect!
The flow of the system can be described as follows:
- CalcServer running on host A gets a "date-string" e.g. 20090220 and converts it to a
java.sql.Date
object using a SimpleDateFormat("yyyyMMdd")
- CalcServer then sends the
java.sql.Date
object to the ResultServer, running on host B, via RMI.
- ResultServer stores the
java.sql.Date
object to a java.sql.Types.DATE
column in my Oracle database.
BUT, when I query my database I see 19-FEB-2009, instead of 20-FEB-2009! What is going on?
After a lot of investigation I found out that host A and host B were in different regions; one in Frankfurt and the other in London. The CalcServer in Frankfurt converts "20090220" into a date of "Fri Feb 20 00:00:00 CET 2009". When the ResultServer in London, deserialises the date it gets "Thu Feb 19 23:00:00 GMT 2009" and hence 19-FEB-2009 is stored in the database.
I have now fixed this by sending the date-string (not the java.sql.Date
object) to the ResultServer, which will then parse it into a java.sql.Date
object for storage.
Here is sample code which can be used to serialise a date on one host and deserialise it on another.
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class SerializationTest {
public static void main(String[] args) throws Exception {
final String yyyyMMdd = "20090220";
final Date date = new SimpleDateFormat("yyyyMMdd").parse(yyyyMMdd);
if (args.length != 1) {
System.out.println("Usage SerializationTest S|D");
}
boolean serialise = false;
if (args[0].equals("S")) {
serialise = true;
}
else if (args[0].equals("D")) {
serialise = false;
}
String filename = "date.ser";
if (serialise) {
// write the object to file
FileOutputStream fos = new FileOutputStream(filename);
BufferedOutputStream bos = new BufferedOutputStream(fos);
ObjectOutputStream outputStream = new ObjectOutputStream(bos);
outputStream.writeObject(date);
outputStream.flush();
outputStream.close();
System.out.println("Serialised: " + date);
}
else {
FileInputStream fis = new FileInputStream(filename);
BufferedInputStream bis = new BufferedInputStream(fis);
ObjectInputStream inputStream = new ObjectInputStream(bis);
Date outDate = (Date) inputStream.readObject();
inputStream.close();
// print the object
System.out.println(outDate);
}
}
}
Link to Stack Overflow Question
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.