将日期保存到 Room 数据库时,TypeConverter 会打乱数据
When saving dates to Room database, TypeConverter scrambles the data
我已经为此工作了几个小时,但我似乎无法弄清楚如何将日期保存到我的 Room Sqllite 数据库中。我基本上是从 Android 文档中复制代码来完成这项工作。
这是我的。
数据库:
@Database(entities = {Review.class},
version = 3,
exportSchema=false)
@TypeConverters(DateTypeConverter.class)
public abstract class NotecardDatabase extends RoomDatabase {
...etc...
}
实体:
@Entity(tableName = "review",
indices = {
@Index(value = "next_review"),
}
public class Review {
...Other columns...
@TypeConverters(DateTypeConverter.class)
@ColumnInfo(name ="next_review")
@NonNull
private Date nextReview;
}
接下来,我的转换器:
public class DateTypeConverter {
private static Logger log = Logger.getLogger("DateTypeConverter");
@TypeConverter
public static Date fromTimestamp(Long value) {
if(value != null) {
log.info("Incoming long: " + value + "\nTo Date: " + new Date(value));
}
return value == null ? null : new Date(value);
}
@TypeConverter
public static Long dateToTimestamp(Date date) {
if(date != null) {
log.info("Incoming date: " + date + "\n to Long: " + date.getTime());
}
return date == null ? null : date.getTime();
}
}
最后,这是我在尝试创建一些评论对象时从 运行 获得的输出:
06-18 18:13:38.522 7081-7098/DateTypeConverter:
传入日期:2018 年太平洋夏令时间 6 月 18 日星期一 18:13:38
长:1529370818524
06-18 18:13:38.522 7081-7106/DateTypeConverter:
来电长:1529370818
迄今为止:周日 1 月 18 08:49:30 PST 1970
所以它似乎保存正确(见第一条日志语句),但是当我从数据库中取出东西时,long 的最后 3 位被简单地切掉,返回 1970 年的日期。
帮忙?
而不是@TypeConverters(DateTypeConverter.class)
使用
@TypeConverters({DateTypeConverter.class})
好的,经过大量工作,我找到了问题所在。感谢所有为此提供帮助的人。
我从日期更改为日历,但这并不能解决这个问题。
真正的问题是有两个时间戳:Linux 时间戳,自纪元以来 毫秒 ,以及 Java/Sqllite 时间戳,即秒 自纪元以来。
为了让所有东西都能很好地与 Sqllite 函数一起使用并正确保存和读取,这是我的工作代码:
public class DateTypeConverter {
@TypeConverter
public static Calendar calendarFromTimestamp(String value) {
if(value == null) {
return null;
}
Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(NumberUtils.toLong(value)*1000);
return cal;
}
@TypeConverter
public static String dateToTimestamp(Calendar cal) {
if(cal == null) {
return null;
}
return "" + cal.getTimeInMillis()/1000;
}
}
注意 cal.getTimeInMillis() 函数的用法,它明确指出我们正在执行 毫秒 时间戳。然后在保存到数据库的时候,我们除以1000来保存seconds时间戳,因为Sqllite日期函数处理的是seconds时间戳。
另请注意,您也可以使用 Longs 而不是 Strings,但 Strings 对我有用。
我已经为此工作了几个小时,但我似乎无法弄清楚如何将日期保存到我的 Room Sqllite 数据库中。我基本上是从 Android 文档中复制代码来完成这项工作。
这是我的。
数据库:
@Database(entities = {Review.class},
version = 3,
exportSchema=false)
@TypeConverters(DateTypeConverter.class)
public abstract class NotecardDatabase extends RoomDatabase {
...etc...
}
实体:
@Entity(tableName = "review",
indices = {
@Index(value = "next_review"),
}
public class Review {
...Other columns...
@TypeConverters(DateTypeConverter.class)
@ColumnInfo(name ="next_review")
@NonNull
private Date nextReview;
}
接下来,我的转换器:
public class DateTypeConverter {
private static Logger log = Logger.getLogger("DateTypeConverter");
@TypeConverter
public static Date fromTimestamp(Long value) {
if(value != null) {
log.info("Incoming long: " + value + "\nTo Date: " + new Date(value));
}
return value == null ? null : new Date(value);
}
@TypeConverter
public static Long dateToTimestamp(Date date) {
if(date != null) {
log.info("Incoming date: " + date + "\n to Long: " + date.getTime());
}
return date == null ? null : date.getTime();
}
}
最后,这是我在尝试创建一些评论对象时从 运行 获得的输出:
06-18 18:13:38.522 7081-7098/DateTypeConverter: 传入日期:2018 年太平洋夏令时间 6 月 18 日星期一 18:13:38 长:1529370818524
06-18 18:13:38.522 7081-7106/DateTypeConverter: 来电长:1529370818 迄今为止:周日 1 月 18 08:49:30 PST 1970
所以它似乎保存正确(见第一条日志语句),但是当我从数据库中取出东西时,long 的最后 3 位被简单地切掉,返回 1970 年的日期。
帮忙?
而不是@TypeConverters(DateTypeConverter.class)
使用
@TypeConverters({DateTypeConverter.class})
好的,经过大量工作,我找到了问题所在。感谢所有为此提供帮助的人。
我从日期更改为日历,但这并不能解决这个问题。
真正的问题是有两个时间戳:Linux 时间戳,自纪元以来 毫秒 ,以及 Java/Sqllite 时间戳,即秒 自纪元以来。
为了让所有东西都能很好地与 Sqllite 函数一起使用并正确保存和读取,这是我的工作代码:
public class DateTypeConverter {
@TypeConverter
public static Calendar calendarFromTimestamp(String value) {
if(value == null) {
return null;
}
Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(NumberUtils.toLong(value)*1000);
return cal;
}
@TypeConverter
public static String dateToTimestamp(Calendar cal) {
if(cal == null) {
return null;
}
return "" + cal.getTimeInMillis()/1000;
}
}
注意 cal.getTimeInMillis() 函数的用法,它明确指出我们正在执行 毫秒 时间戳。然后在保存到数据库的时候,我们除以1000来保存seconds时间戳,因为Sqllite日期函数处理的是seconds时间戳。
另请注意,您也可以使用 Longs 而不是 Strings,但 Strings 对我有用。