I'm looking for a proper serializable date-only class. Got a server in Central time zone, I want users in the Eastern to enter date as 2010-11-23, and users in Pacific to see it as 2010-11-23 (and vice versa).
java.util.Date
is a time-sensitive instant, so it doesn't work for me. Not wanting to reinvent the wheel, I decided to give Joda Time a try. According to overview, LocalDate
is a "class representing a local date without a time (no time zone)" - just what I need.
Unfortunately, it does not seem to be time zone independent. In database I have 2010-11-23. On server, I transform it to LocalDate
with new LocalDate(java.sql.Date)
. date.toString()
prints 2010-11-23.
After deserializing that on client, date.ToString()
prints 2010-11-22 and date.getDayOfMonth()
is 22. But date.toDateTimeAtStartOfDay()
produces 2010-11-23T00:00:00.000-08:00.
Am I doing something wrong? Is there a proper date-only time zone insensitive class in Joda?
EDIT: In database I am using a timezone insensitive column (DATE
in Postgres). Server is in the same time zone as the database, so it reads the date just fine. It is not an issue. I am looking for a Java type that once instantiated in one time zone, has the same civil (partial) date value in all time zones.
EDIT 2: On server everything is loaded properly and has UTC time zone. After investigation I think it is a bug in ISOChronology
. On client it is unpacked as America/Los_Angeles. The reason is that serialization is done with:
class ISOChronology {
// ...
private Object writeReplace() {
return new Stub(getZone());
}
private static final class Stub implements Serializable {
private static final long serialVersionUID = -6212696554273812441L;
private transient DateTimeZone iZone;
Stub(DateTimeZone zone) {
iZone = zone;
}
private Object readResolve() {
return ISOChronology.getInstance(iZone);
}
private void writeObject(ObjectOutputStream out) throws IOException {
out.writeObject(iZone);
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
iZone = (DateTimeZone)in.readObject();
}
}
}
Good luck serializing with a transient field.
The trasient
time zone in the stub class shown above is a bug. Amazing that it wasn't caught in tens of thousands of tests or 5 years of widespread usage. Bug report https://sourceforge.net/tracker/index.php?func=detail&aid=3117678&group_id=97367&atid=617889
The timezone should be UTC, as defined in the Javadoc - http://joda-time.sourceforge.net/apidocs/org/joda/time/LocalDate.html . Deserializing to get any other time zone will break the internal state of the class.
JSR-310 uses a much better internal design which doesn't suffer from this kind of problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With