我正在寻找一个合适的可序列化的仅限日期的类。有一台位于中部时区的服务器,我希望东部地区的用户输入日期为 2010-11-23,而太平洋地区的用户将其视为 2010-11-23(反之亦然)。
java.util.Date
是一个时间敏感的时刻,所以它对我不起作用。不想重新发明轮子,我决定尝试一下 Joda Time。根据概述,LocalDate
是一个“表示没有时间(无时区)的本地日期的类”——正是我所需要的。
不幸的是,它似乎与时区无关。在数据库中我有 2010-11-23。在服务器上,我使用 new LocalDate(java.sql.Date)
将其转换为 LocalDate
。 date.toString()
打印 2010-11-23。
在客户端反序列化之后,date.ToString()
打印 2010-11-22 而 date.getDayOfMonth()
是 22。但是 date.toDateTimeAtStartOfDay ()
生成 2010-11-23T00:00:00.000-08:00。
我做错了什么吗? Joda 中是否有适当的仅日期时区不敏感类?
编辑:在数据库中我使用时区不敏感列(DATE
在 Postgres 中)。服务器与数据库处于同一时区,因此它可以很好地读取日期。这不是问题。 我正在寻找一种 Java 类型,它一旦在一个时区实例化,在所有时区都具有相同的民用(部分)日期值。
编辑 2:在服务器上,所有内容都正确加载并且具有 UTC 时区。经过调查,我认为这是 ISOChronology
中的错误。在客户端,它被解压为 America/Los_Angeles。原因是序列化是通过以下方式完成的:
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();
}
}
}
祝你在使用 transient 字段序列化时好运。
最佳答案
上面显示的 stub 类中的 trasient
时区是一个错误。令人惊讶的是,它没有在数万次测试或 5 年的广泛使用中被发现。错误报告 https://sourceforge.net/tracker/index.php?func=detail&aid=3117678&group_id=97367&atid=617889
时区应为 UTC,如 Javadoc 中所定义 - http://joda-time.sourceforge.net/apidocs/org/joda/time/LocalDate.html .反序列化以获取任何其他时区将破坏类的内部状态。
JSR-310 使用更好的内部设计,不会出现此类问题。
关于java - Joda LocalDate - 还是瞬间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4268472/