比较 Room 数据库中的日期

exo*_*nik 1 android date kotlin

我有这个 Entry 数据类

@Entity(tableName = "entry")
@Typeconverters(DateConverter::class)
data class Entry(

    @PrimaryKey(autoGenerate = false)
    var id : String,
    var username : String,
    var type : String,
    var description : String,
    var category : String,
    var amount : Double,
    var date : String,
    var lastUpdate : String,
    var isDeleted : Boolean)
}
Run Code Online (Sandbox Code Playgroud)

日期字段包含一个表示“yyyy-MM-dd”格式的日期的字符串,而lastUpdate 包含一个表示“yyyy-MM-dd hh:mm:ss”格式的日期的字符串。如果我将这些变量存储为字符串,我无法对它们进行 SQL 比较,因为 Room 不支持 SQL 的 DATE() 和 DATETIME() 数据类型,因此查询如下:

@Query(SELECT * FROM entry WHERE date >= :fromDate AND date <= :untilDate)
Run Code Online (Sandbox Code Playgroud)

将无法正常工作。有没有什么办法解决这一问题?

mue*_*flo 5

嗯,我看到了 3 个选项。

\n
    \n
  1. 由于您的日期字符串以良好的分层方式(年、月、日)进行格式化,因此您实际上应该能够使用其自然的字符串排序。

    \n
  2. \n
  3. 如果您需要在 SQL 查询中进行真实日期排序,则必须将日期保存为真实日期字段或整数字段(Unix 纪元时间戳)

    \n
  4. \n
  5. 如果可以在从数据库获取日期之后或将其存储到数据库之前对日期进行排序,请熟悉 Room 中的 TypeAdapter。这是一个简单的转换类,您可以在字符串和日期时间之间进行相互转换。

    \n
  6. \n
\n

为了回答您的第二个问题,即为什么不支持开箱即用的这种“常见”数据类型,我可以推荐这篇中等文章

\n
\n

SQLite 是一种松散类型的数据库系统,并将所有值存储为以下之一:NULL、INTEGER、TEXT、REAL 或 BLOB。您\xe2\x80\x99 会注意到,\n没有像其他数据库系统中那样的特殊日期或时间类型。

\n

相反,他们提供了有关如何存储\n日期/时间值的以下文档:\nSQLite 没有为\n存储日期和/或时间预留的存储类。相反,SQLite 的内置日期和时间\n函数能够将日期和时间存储为 TEXT、\nREAL 或 INTEGER 值

\n
\n

如果你进一步思考,问题就出现了:什么是通用数据类型以及“通用”到底在哪里。当然,他们可以提供一些类型转换器,但另一方面,它只是针对每种数据类型的几行代码。

\n

以下是从日期到字符串并返回的类型转换器的示例:

\n
public class Converters {\n  @TypeConverter\n  public static Date fromTimestamp(Long value) {\n    return value == null ? null : new Date(value);\n  }\n\n  @TypeConverter\n  public static Long dateToTimestamp(Date date) {\n    return date == null ? null : date.getTime();\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n