デバイスのタイムゾーンを変更すると、Ormliteで読み取られた日付が正しく返されないことがわかりました。
たとえば、アムステルダム時間からロンドン時間に切り替える場合、日付は1時間前にシフトする必要があります。ただし、データベースから日付を読み取ると、同じ時刻が返されますが、現在はロンドンのタイムゾーンになっています。
私は自分のフィールドを次のように保存しています:
@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が日付フィールドを保持する方法を構成するグローバルな方法を探している場合は、DataPersisterManager
クラス(Github)を使用できます。
たとえば、デフォルトのタイムゾーンのない文字列ではなく、UTC(エポックからのミリ秒)ですべての日付をLongsとして保存するには、次のようにします。
DataPersisterManager.registerDataPersisters(DateLongType.getSingleton());
その場合、各日付フィールドをで構成する必要はありませんdataType = DataType.DATE_LONG
。