我发现更改设备时区时,通过 Ormlite 读取的日期无法正确返回。
例如,当从阿姆斯特丹时间切换到伦敦时间时,日期应该向前移动一个小时。但是,当从数据库中读取日期时,它会返回相同的时间,但现在是伦敦时区。
我按如下方式存储我的字段:
@DatabaseField(canBeNull = true)
private Date registration;
查看数据库,我发现 Ormlite 默认Date
以YYYY-MM-DD HH:MM:SS.SSS
. 由于没有关于时区的信息,它假定设备的当前时区。
诀窍是将其存储在 UTC 时间戳中:
@DatabaseField(canBeNull = true, dataType = DataType.DATE_LONG)
private Date registration;
如果您想亲自编写自己的持久化器,可以这样做:
@DatabaseField(persisterClass = DateConverter.class)
private Date registration;
在哪里:
public static class DateConverter extends LongType {
private static final DateConverter singleton = new DateConverter();
protected DateConverter() {
super(SqlType.LONG, new Class<?>[] {
Date.class
});
}
public static DateConverter getSingleton() {
return singleton;
}
@Override
public Object javaToSqlArg(FieldType fieldType, Object javaObject)
throws SQLException {
if (javaObject instanceof Date) {
return ((Date) javaObject).getTime();
}
return javaObject;
}
@Override
public Object sqlArgToJava(FieldType fieldType, Object sqlArg, int columnPos)
throws SQLException {
if (sqlArg instanceof Long) {
return new Date((Long) sqlArg);
}
return null;
}
}
如果您正在寻找一种全局方式来配置 OrmLite 如何持久保存 Date 字段,您可以使用DataPersisterManager
该类 ( Github )。
例如,要将所有日期保存为 UTC 中的 Longs(自纪元以来的毫秒数)而不是默认值,即没有时区的字符串,您可以这样做:
DataPersisterManager.registerDataPersisters(DateLongType.getSingleton());
那么就不需要为每个 Date 字段配置dataType = DataType.DATE_LONG
.