SQLite3日期与时间

本文讨论SQLite3数据库中的日期和时间数据处理。

首先了解日期与时间处理相关的函数。

  • strftime(format,timestring,modifier1,modifier2,...)函数,可以进行日期时间字符串的转换、格式化和推算。
  • datetime(timestring, modifier,...)函数,返回转换后的YYYY-MM-DD HH:MM:SS格式日期和时间字符串。相当于strftime('%Y-%m-%d %H:%M:%S',timestring,...)。
  • date(timestring,modifier,...)函数,返回转换后的YYYY-MM-DD格式日期值。相当于strftime('%Y-%m-%d',tiemstring,...)。
  • time(timestring, modifier,...)函数,返回转换后的HH:MM:SS格式时间字符串。相当于strftime('%H:%M:%S',timestring,...)。
  • julianday(timestring,modifier,...)函数返回Julian Day数值。相当于strftime('%J',timestring,...)。

这些函数中,format参数定义格式化字符串,其中可以使用的格式化字符如下表所示。

格式化字符功能
%d月中的第几天,01-31。
%f秒和毫秒(SS.sss),00-59加小数部分。
%H时,00-23。
%j一年中的第几天,001-366。
%JJulian Day数值(DDDDDDD.ddddddd)。
%m月份,01-12。
%M分钟,00-59。
%s自1970-01-01(Unix epoch)以来的秒数。
%S秒,00-59。
%w周几(N),0为周日。
%W一年中的第几周,00-53。
%Y四位年份。
%%显示%字符。

timestring参数指定文本形式的日期和时间信息,允许的格式如下表所示:

格式说明
YYYY-MM-DD年-月-日
YYYY-MM-DD HH:MM年-月-日 时:分
YYYY-MM-DD HH:MM:SS年-月-日 时:分:秒
YYYY-MM-DD HH:MM:SS.sss年-月-日 时:分:秒.毫秒
YYYY-MM-DDTHH:MM年-月-日T时:分,T为ISO标准中的时间字符
YYYY-MM-DDTHH:MM:SS年-月-日T时:分:秒,T为ISO标准中的时间字符
YYYY-MM-DDTHH:MM:SS.sss年-月-日T时:分:秒.毫秒,T为ISO标准中的时间字符
HH:MM时:分
HH:MM:SS时:分:秒
HH:MM:SS.sss时:分:秒.毫秒
now系统当前时间
DDDDDDDJulian Day
DDDDDDD.dddddddJulian Day

modifier参数中可以使用的修饰符如下表所示:

修饰符说明
[+-]NNN day[s]指定向后或向前推算的天数
[+-]NNN hour[s]指定向后或向前推算的小时数
[+-]NNN minute[s]指定向后或向前推算的分钟数
[+-]NNN second[s]指定向后或向前推算的秒数
[+-]NNN.nnn second[s]指定向后或向前推算的秒和毫秒数
[+-]NNN month[s]指定向后或向前推算的月数
[+-]NNN year[s]指定向后或向前推算的年数
start of year返回年度中的第一天。
start of month返回月份中的第一天。
start of day返回一天的0点。
weekday N返回等于或晚于当前时间的周几(N)的日期时间。0表示周日,1到6表示周一到周六。
unixepochUNIX时间。
localtime本地时间。
utcUTC时间。

此外,还可以使用如下关键字获取系统当前日期和时间:

  • CURRENT_TIME,获取HH:MM:SS格式的UTC时间。
  • CURRENT_DATE,获取YYYY-MM-DD格式的UTC日期。
  • CURRENT_TIMESTAMP,获取YYYY-MM-DD HH:MM:SS格式的UTC日期和时间。

下面来看一些应用实例。

获取系统时间

下面的代码会使用datetime()函数获取系统当前时间。

SQLite3
select datetime('now'), datetime('now','localtime');

代码中,datetime()函数的时间字符串使用了'now',用于获取系统的当前时间,第一次调用,默认返回系统时间对应的UTC时间;第二次调用,在修饰符中使用'localtime',指定返回本地时间。测试计算机设置为北京时间(正八区),第一次调用比第二次调用的结果早8个小时。

单独获取日期或时间也可以使用相同的参数,如下面的代码。

SQLite3
select date('now','localtime'), time('now','localtime');

执行代码会返回系统的本地日期和时间。

获取当前年、月、日、时、分、秒等数据时,可以在strftime()函数中使用对应的格式化字符,如下面的代码会分别显示系统本地时间中的时、分、秒。

SQLite3
select strftime('%H','now','localtime'),
strftime('%M','now','localtime'),
strftime('%S','now','localtime');

时间的推算

时间的推算同样使用函数的修饰符来完成,如下面的代码会在系统本地时间加上3个小时,即向后推算3小时。

SQLite3
select datetime('now','localtime','+3 hour');

向前推算时应在修饰符中使用负值,如下面的代码会在系统当前本地时间上向前推算3小时30分。

SQLite3
select datetime('now','localtime','-3.5 hour');

数据表中的日期和时间

在数据库中保存日期和时间时,应约定保存UTC时间还是本地时间,如何需要处理多时区的数据,使用UTC是合理的选择,如果只处理本地数据,使用本地时间则会更加直观。

数据表中使用文本类型(text)的字段保存日期和时间信息,保存系统当前时间时,current_date、current_time和current_timestamp会返回系统当前UTC时间,如果需要保存系统中的本地时间,需要使用对应的函数和参数。

下面的代码是创建t1表的代码,测试中如果表格已存在可以删除后重新创建。

SQLite3
create table t1(
f1 text not null unique,
f2 integer default 0,
f3 text,
f4 text);

下面的代码会在t1表中添加3条记录,其中,f3字段保存为日期和时间信息。

SQLite3
insert into t1(f1,f3)
values('user01','2025-09-29 10:11:12'),
('user02','2025-09-29 11:15:33'),
('user03','2026-06-03 11:35:16');

下面的代码,会继续向t1表中添加3条记录,其中,f3字段保存当前系统的本地时间。

SQLite3
insert into t1(f1,f3)
values('user04',datetime('now','localtime')),
('user05',datetime('now','localtime')),
('user06',datetime('now','localtime'));

下面的代码可以查询f3中年份为2025的记录。

SQLite3
select * from t1 where strftime('%Y',f3)='2025';

查询结果如下图所示。

查询结果

下面的代码会查询f3字段数据为2026年6月的数据。

SQLite3
select * from t1 
where strftime('%Y',f3)='2026' and strftime('%m',f3)='06';

查询结果如下图所示。

查询结果

查询某一天的记录时,可以使用date()函数读取字段数据后比较,如下面的代码查询f3字段数据为2025年9月29日的记录。

SQLite3
select * from t1 where date(f3)='2025-09-29';

查询结果如下图所示。

查询结果

查询一个日期和时间区间时,条件设置应大于小于最小时间点,并小于允许最大值的下一时点;下面的条件会以天为单位,查询2025年9月1日到9月30日的记录。

SQLite3
select * from t1 where f3>='2025-09-01' and f3<'2025-10-1';

本例设置的条件,f3字段大于等于2025年9月1日零点,且小于2025年10月1日零点,这样就包含了2025年9月的所有时间点。

查询单位为其它元素时也使用相似的方法,如下面代码。

SQLite3
select * from t1 where f3>='2025-09-29 10:00:00' and f3<'2025-09-29 11:00:00';

本例设置的条件,可以查询f3字段2025年9月29日10点到11点之间的记录,查询结果如下图所示。

查询结果