我需要能够使用Room TypeConverters在我的sqlite数据库上存储和检索LocalDateTime属性。
经过一些研究,我实现了下面的转换器。然而,这个转换器似乎只存储默认日期时间(1970-01-01)。所以转换不正确。有人有一个工作的LocalDateTime转换器吗?或者对此有任何改进吗?
public class LocalDateTimeConverter {
@TypeConverter
public static LocalDateTime toDate(Long timestamp) {
LocalDateTime ldt;
if (timestamp == null){
return null;
}else{
ldt = Instant.ofEpochMilli(timestamp).atZone(ZoneId.systemDefault()).toLocalDateTime();
}
return ldt;
}
@TypeConverter
public static Long toTimestamp(LocalDateTime date) {
if (date == null){
return null;
}else {
return date.getLong(ChronoField.CLOCK_HOUR_OF_DAY);
}
}}
我已经在我的库Suitcase中实现了一个LocalDateTimeConverter
。请记住,这在这里扩展了我的 BaseConverter
类。注意:这一切都在 Kotlin 中。
如果你想实现自己,我建议将 is 存储为字符串而不是时间戳。如果你查看上面的链接,你会看到我首先使用 toString
() 将日期转换为字符串,然后使用 parse()
函数返回 LocalDateTime
。
这里是Java语言:
public class LocalDateTimeConverter {
@TypeConverter
public static LocalDateTime toDate(String dateString) {
if (dateString == null) {
return null;
} else {
return LocalDateTime.parse(dateString);
}
}
@TypeConverter
public static String toDateString(LocalDateTime date) {
if (date == null) {
return null;
} else {
return date.toString();
}
}
}
编辑:
您在上面使用的代码不起作用的原因是,在您的toTimestamp()
函数中,您只是将一天中的小时作为Long
询问。因此,给定2019年1月1日下午12:00的LocalDateTime
,您正在存储12
。因此,在toDate
中,您要求将时间戳12
转换为LocalDateTime
,这将是1970年1月1日午夜后的12毫秒。
您可以选择继续使用时间戳来存储日期,只需将 toTimestamp
() 中的该行更改为 date.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()
。这将为您提供当前时区中本地日期时间
的实际时间戳。请注意此处的时区:当您使用系统的默认时区来保存/加载到/从数据库加载时,如果系统更改时区,您可能会得到错误的值。如果我在纽约使用您的应用程序,然后在旧金山重新打开该应用程序,则所有时间都将关闭 3 小时。最好使用设置的时区来保存/加载,然后将其转换为设备的当前时区。