SQLite 可以使用文本、实数或整数数据类型来存储日期。
更重要的是,无论何时执行查询,结果都会以%Y-%m-%d %H:%M:%S 格式显示。
现在,如果您使用 SQLite 日期/时间函数插入/更新日期/时间值,您实际上也可以存储毫秒。
如果是这种情况,则使用格式%Y-%m-%d %H:%M:%f 显示结果。
例如:
sqlite> create table test_table(col1 text, col2 real, col3 integer);
sqlite> insert into test_table values (
strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.123'),
strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.123'),
strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.123')
);
sqlite> insert into test_table values (
strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.126'),
strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.126'),
strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.126')
);
sqlite> select * from test_table;
2014-03-01 13:01:01.123|2014-03-01 13:01:01.123|2014-03-01 13:01:01.123
2014-03-01 13:01:01.126|2014-03-01 13:01:01.126|2014-03-01 13:01:01.126
现在,做一些查询来验证我们是否真的能够比较时间:
sqlite> select * from test_table /* using col1 */
where col1 between
strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.121') and
strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.125');
2014-03-01 13:01:01.123|2014-03-01 13:01:01.123|2014-03-01 13:01:01.123
您可以使用col2 和col3 检查相同的SELECT,您将得到相同的结果。
如您所见,没有返回第二行(126 毫秒)。
请注意,BETWEEN 包含在内,因此...
sqlite> select * from test_table
where col1 between
/* Note that we are using 123 milliseconds down _here_ */
strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.123') and
strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.125');
... 将返回相同的集合。
尝试使用不同的日期/时间范围,一切都会按预期运行。
没有strftime函数怎么办?
sqlite> select * from test_table /* using col1 */
where col1 between
'2014-03-01 13:01:01.121' and
'2014-03-01 13:01:01.125';
2014-03-01 13:01:01.123|2014-03-01 13:01:01.123|2014-03-01 13:01:01.123
没有strftime函数又没有毫秒怎么办?
sqlite> select * from test_table /* using col1 */
where col1 between
'2014-03-01 13:01:01' and
'2014-03-01 13:01:02';
2014-03-01 13:01:01.123|2014-03-01 13:01:01.123|2014-03-01 13:01:01.123
2014-03-01 13:01:01.126|2014-03-01 13:01:01.126|2014-03-01 13:01:01.126
ORDER BY 呢?
sqlite> select * from test_table order by 1 desc;
2014-03-01 13:01:01.126|2014-03-01 13:01:01.126|2014-03-01 13:01:01.126
2014-03-01 13:01:01.123|2014-03-01 13:01:01.123|2014-03-01 13:01:01.123
sqlite> select * from test_table order by 1 asc;
2014-03-01 13:01:01.123|2014-03-01 13:01:01.123|2014-03-01 13:01:01.123
2014-03-01 13:01:01.126|2014-03-01 13:01:01.126|2014-03-01 13:01:01.126
工作得很好。
最后,在处理程序中的实际操作时(不使用 sqlite 可执行文件...)
顺便说一句:我正在使用 JDBC(不确定其他语言)...来自xerial 的 sqlite-jdbc 驱动程序 v3.7.2 - 也许较新的版本会改变下面解释的行为...
如果您在 Android 中进行开发,则不需要 jdbc-driver。所有 SQL 操作都可以使用SQLiteOpenHelper 提交。
JDBC 有不同的方法从数据库中获取实际的日期/时间值:java.sql.Date、java.sql.Time 和 java.sql.Timestamp。
java.sql.ResultSet中的相关方法(显然)分别是getDate(..)、getTime(..)和getTimestamp()。
例如:
Statement stmt = ... // Get statement from connection
ResultSet rs = stmt.executeQuery("SELECT * FROM TEST_TABLE");
while (rs.next()) {
System.out.println("COL1 : "+rs.getDate("COL1"));
System.out.println("COL1 : "+rs.getTime("COL1"));
System.out.println("COL1 : "+rs.getTimestamp("COL1"));
System.out.println("COL2 : "+rs.getDate("COL2"));
System.out.println("COL2 : "+rs.getTime("COL2"));
System.out.println("COL2 : "+rs.getTimestamp("COL2"));
System.out.println("COL3 : "+rs.getDate("COL3"));
System.out.println("COL3 : "+rs.getTime("COL3"));
System.out.println("COL3 : "+rs.getTimestamp("COL3"));
}
// close rs and stmt.
由于 SQLite 没有实际的 DATE/TIME/TIMESTAMP 数据类型,所有这 3 个方法都返回值,就好像对象是用 0 初始化的一样:
new java.sql.Date(0)
new java.sql.Time(0)
new java.sql.Timestamp(0)
所以,问题是:我们如何才能实际选择、插入或更新 Date/Time/Timestamp 对象?没有简单的答案。
您可以尝试不同的组合,但它们会迫使您在所有 SQL 语句中嵌入 SQLite 函数。在 Java 程序中定义一个实用程序类来将文本转换为 Date 对象要容易得多。但请始终记住,SQLite 会将任何日期值转换为 UTC+0000。
总之,尽管一般规则总是使用正确的数据类型,或者甚至表示 Unix 时间的整数(自纪元以来的毫秒数),但我发现使用默认 SQLite 格式('%Y-%m-%d %H:%M:%f' 或 Java 中的 'yyyy-MM-dd HH:mm:ss.SSS' 更容易) ) 而不是使用 SQLite 函数使所有 SQL 语句复杂化。前一种方法更容易维护。
TODO:我会在 Android 内部使用 getDate/getTime/getTimestamp(API15 或更高版本)时检查结果...可能内部驱动程序与 sqlite-jdbc 不同...