我一直在寻找,但我仍然无法理解这是如何运作的。
我知道SQLite不存储Date类型值,我们必须将它们格式化为TEXT。我已经这样做了,但我的问题是如何按日期删除它们?
因为如果我DELETE * FROM TABLE WHERE COLUMN_DATE >= '09-05-2017'
,我会比较字符串而不是日期,所以我猜比较不对。
我已经看到人们进行这些类型的比较,即使它是TEXT类型。我对我没有意义。
答案 0 :(得分:2)
如果您使用规范文本格式并使用正确的语法,例如
,它将起作用DELETE FROM TABLE WHERE COLUMN_DATE >= '2017-05-09'
答案 1 :(得分:0)
在SQLite边日期比较/算术方面更有效和更简单的方法是将日期存储为SQLite中的INT
。
Date
实际上只是毫秒级的容器 - 自1970年1月1日以来的UTC时间(自UTC时间1970年1月1日起),与时区无关。
INT
是根据列中的值自动选择的1,2,4,8字节数据类型。
为了在数据库中存储数据时将Java Date
转换为SQLite INT
值,请使用getTime()
方法:
Date javaDate = ...;
long sqlDate = date.getTime();
要从SQLite中检索日期,请使用Cursor
的{{1}}方法并将其传递给Date(long)
构造函数:
getLong()
答案 2 :(得分:0)
示例:
LocalDate ld = LocalDate.of( 2017 , Month.JANUARY , 23 ) ; // Or `LocalDate.parse`, or `LocalDate.now()`.
String sql = "DELETE * FROM tbl WHERE col >= '" + ld.toString() + "' ;" ;
请记住SQLite was never meant to be a heavy-duty database,这只是将文本写入文件的一步。因此,如果您需要复杂的日期时间支持,则应切换到更复杂的数据库。
SQLite缺少正确的数据类型,正如您在问题中提到的那样。对于存储日期时间类型,the documentation suggests three routes :( a)ISO 8601字符串,(b)表示朱利安日数的实数(我不推荐这个),以及(c)存储数字的整数自UTC中1970年第一时刻的纪元参考以来的秒数,如Answer by Abakumov所示(尽管你不应该使用那里显示的Date
类)。
您似乎正在跟踪仅限日期的值,而不是一天中的某个时间。所以我会将ISO 8601用于文本:YYYY-MM-DD。
在解析/生成日期时间值时,Java中的 java.time 类型默认使用标准ISO 8601格式。 Java中仅限日期的类是LocalDate
,缺少时间和缺少时区。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate today = LocalDate.now( z ) ;
指定日期。
LocalDate ld = LocalDate.parse( "2017-09-05" ) ; // Standard ISO 8601 format for input: YYYY-MM-DD.
标准ISO 8601格式的优点是字母顺序恰好也是按时间顺序排列。
因此,您可以使用大于/小于逻辑来进行基于文本的比较。
String sql = "DELETE * FROM tbl WHERE col >= '" + ld.toString() + "' ;" ;
与其他两种方法相比的另一大优势:
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
从哪里获取java.time类?