使用 Android 房间只比较没有时间的日期

Compare only date without time using Android Room

我正在使用 Room 的 TypeConverter 将 Date 对象保存到数据库中。它工作得很好。但是,我想进行一个查询,只比较日期对象的“日期”部分和时间戳的“日期”部分。我希望时间被忽略。我尝试使用 SQLite 上可用的 date() 函数,但我想我用错了。

@Query("SELECT * FROM event WHERE date(event_date) = date(:date)")
fun loadEventsByDate(date: Date): Flow<List<Event>>
class DateConverter {
    @TypeConverter
    fun fromTimestamp(value: Long?): Date? {
        return value?.let { Date(it) }
    }

    @TypeConverter
    fun dateToTimestamp(date: Date?): Long? {
        return date?.time
    }
}

Issue/Explanation

您的问题是您正在转换 to/from(并因此存储)以毫秒为单位的 unix 日期时间,但是 SQLite date 函数 (以及所有 SQLite date/time 函数) 期望 date/time 匹配其中一种可识别的格式。

这是一个示例(使用被劫持的项目,因此使用用户 table)如何使用类型转换器(日期列)存储数据:-

13位

因此 date 函数 returns NULL(对于 WHERE 子句的两边)并且在 SQLite 中 NULL 不等于 NULL 因此你什么也得不到(如果 NULL 等于 NULL 你会获取所有行而不是选择)。

根据以上数据考虑以下解释性查询(修复了 WHERE 子句):-

@Query("SELECT *, :date AS passed_date, coalesce(date(date),'ouch') AS cnv_date, coalesce(date(:date),'ouch') AS cnv_passed_date FROM user WHERE date(date / 1000,'unixepoch') = date(:date / 1000,'unixepoch');")

结果(使用上面的示例数据)将是(将其写入日志后):-

2021-08-04 08:02:42.324 D/MYINFO: User = Susan date is Wed Aug 04 08:02:42 GMT+10:00 2021 passed date is 1628028162323 converted date is ouch converted passed date is ouch
2021-08-04 08:02:42.325 D/MYINFO: User = Fred date is Wed Aug 04 08:02:42 GMT+10:00 2021 passed date is 1628028162323 converted date is ouch converted passed date is ouch
2021-08-04 08:02:42.325 D/MYINFO: User = Mary date is Wed Aug 04 08:02:42 GMT+10:00 2021 passed date is 1628028162323 converted date is ouch converted passed date is ouch
  • 即Room 处理了提取日期的问题,没有任何问题。然而:-
  • 通过参数传递的日期是13位数字,所以不是日期。因此:-
  • 日期函数均返回 NULL(由合并函数转换为 ouch),因为传递的值是 1 个 13 位无法识别的 date/time 值。

The/A修复

上面的 where 子句包含一个修复程序,确保为日期函数传递一个 suitable 值。即 13 位数字除以 1000 以除去毫秒,然后应用 unixepoch 修饰符。

因此你可以 try/use:-

@Query("SELECT * FROM event WHERE date(event_date / 1000,'unixepoch') = date(:date / 1000,'unixepoch')")
fun loadEventsByDate(date: Date): Flow<List<Event>>