SQLite的日期时间的存储

本文介绍如何在SQLite数据库中使用Java存储和检索日期时间信息,包括数据类型选择、毫秒数存储方式及日期区间查询技巧。


转载自https://segmentfault.com/a/1190000003008234


SQLite中,原始的存储只有以下几种(SQLite文档)

  • NULL。只有null。
  • INTEGER。有符号整数,根据值的大小存储在1-4字节中。
  • REAL。浮点数,储存为8字节的IEEE浮点数。
  • TEXT。文字字符串,根据数据库编码存储(UTF-8/UTF-16BE/UTF-16LE)
  • BLOB。纯数据储存。

Android和Java怎么做

Java中,时间和日期相关类主要是以下:

  • java.util.Date

和它的子类:

  • java.sql.Date
  • java.sql.Time
  • java.sql.Timestamp

以及相关的操作类:

  • java.util.Calendar
  • java.util.GregorianCalendar

用哪个?

其中,java.sql下的DateTime分别是“阉割”了的java.util.Date,而java.sql.Timestamp是强化版增加了微秒的java.util.Date,综上所述,一般而言,用java.util.Date即可。

怎么用?

Java中日期和时间都是通过1970年后的毫秒数来储存的,所以,我们在数据库种只需要存储日期时间的毫秒数即可,调用

java.util.Date date = new java.util.Date();
long datetime = date.getTime();

数据库可以这么定义:

CREATE TABLE IF NOT EXISTS Journal(
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    content TEXT,
    writeTime INTEGER
);

这个地方其实我被折腾了很久,因为Java中用long来存储毫秒数,即int64,但SQLite中只有INTEGER,后来看了文档,这里的INTEGER是支持1-4字节,即可以存储long

插入可以这么来:

java.util.Date writeTime = new java.util.Date();
ContentValues values = new ContentValues();
values.put("content", content);
values.put("writeTime", writeTime.getTime());

按日期查找……WTF?

日期区间查找

由于在数据库内部使用了毫秒的方式储存时间日期,那对于某一个日期,比如2015-07-21这一天的内容如何查找?

其实也就是查找2015-07-21 00:00:00到2015-07-22 00:00:00之间的数值,我们造一个就是了。

首先,获取当前时间

Date now = new Date();

将它处理:

GregorianCalendar cal = new GregorianCalendar();
cal.setTime(now);
//可以根据需要设置时区
//cal.setTimeZone(TimeZone.getDefault());
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
//毫秒可根据系统需要清除或不清除
cal.set(Calendar.MILLISECOND, 0);
long startTime = cal.getTimeInMillis();

结束时间加上即可:

long endTime = startTime + 24 * 3600 * 1000;

现在就可以查询了:

Cursor cursor = db.rawQuery("SELECT * FROM Journal WHERE “ +
    ”writeTime>=? and writeTime<?",
    new String[] { String.valueOf(startTime), String.valuesOf(endTime) });
### SQLite 中与 1900 年相关的日期处理 SQLite 提供了强大的日期和时间处理功能,能够轻松处理与日期相关的查询。在 SQLite 中,`datetime()` 函数可以用于格式化和转换日期时间值。当涉及到 1900 年的日期时,SQLite 的处理方式主要依赖于输入的时间戳或字符串格式,并结合特定的修饰符(如 `'utc'` 或 `'localtime'`)进行调整。 在 SQLite 中,如果使用 `datetime()` 函数并传入一个类似于 `1900-01-01 08:00:00` 的字符串,SQLite 会根据提供的修饰符返回不同的结果。例如,当使用 `'utc'` 修饰符时,SQLite 将假设输入时间为 UTC 时间,并将其转换为标准的 UTC 表示形式[^3]。另一方面,使用 `'localtime'` 修饰符时,SQLite 会将输入时间转换为本地时区的时间表示形式。 以下是一个示例代码,展示如何在 SQLite 中处理与 1900 年相关的日期: ```sql -- 原始数据表 CREATE TABLE test ( id INTEGER, s6 TEXT, status INTEGER ); -- 插入示例数据 INSERT INTO test (id, s6, status) VALUES (7, '1900-01-01 08:00:00', 0); INSERT INTO test (id, s6, status) VALUES (8, '1900-01-01 08:00:00', 0); INSERT INTO test (id, s6, status) VALUES (9, '1900-01-01 08:00:00', 1); -- 查询 UTC 时间 SELECT datetime(s6, 'utc') AS utc_time, s6 FROM test; -- 查询本地时间 SELECT datetime(s6, 'localtime') AS local_time, s6 FROM test; ``` 从上述查询中可以看到,对于 `1900-01-01 08:00:00` 这样的日期时间值,SQLite 能够正确地将其转换为 UTC 或本地时间表示形式。需要注意的是,SQLite 的日期和时间函数默认支持格里高利历(Gregorian calendar),因此对于 1900 年及之后的日期处理是准确的[^3]。 此外,SQLite 在创建表时虽然允许忽略数据类型,但建议明确指定数据类型以增强程序的可读性和一致性。例如,在定义包含日期字段的表时,可以使用 `TEXT` 类型来存储日期时间值,因为 SQLite 的日期和时间函数通常期望输入为 `TEXT` 格式[^2]。 ### 注意事项 尽管 SQLite 能够很好地处理 1900 年及之后的日期,但在处理非常早期的日期(如 1900 年之前)时需要特别小心。SQLite 的日期和时间函数基于格里高利历,而许多国家在 1582 年之后才开始采用该历法。因此,对于早于 1582 年的日期,SQLite 的结果可能不完全符合历史事实。 --- ###
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值