Small. Fast. Reliable.
Choose any three.
日期和时间功能

1.概述

SQLite支持五个日期和时间函数,如下所示:

  1. 日期(时间值,修饰符,修饰符,...
  2. 时间(时间值,修饰符,修饰符,...
  3. datetime(时间值,修饰符,修饰符,...
  4. julianday(时间值,修饰符,修饰符...
  5. strftime(格式,时间值,修饰符,修饰符...

所有五个日期和时间函数均以时间值作为参数。时间值后跟零个或多个修饰符。strftime()函数还将格式字符串作为其第一个参数。

日期和时间功能使用 IS0-8601日期和时间格式的子集。date()函数以以下格式返回日期:YYYY-MM-DD。time()函数将时间返回为HH:MM:SS。datetime()函数返回“ YYYY-MM-DD HH:MM:SS”。julianday()函数返回儒略日Julian day) -公元前4714年11月24日(格林尼治公历)自格林威治中午以来的天数。strftime()例程返回根据指定为第一个参数的格式字符串设置格式的日期。格式字符串支持strftime()函数中最常见的替换 从标准C库中添加了两个新替代品%f和%J。以下是有效的strftime()替换的完整列表:

%d 一个月中的一天:00
%F 小数秒:SS.SSS
%H 小时:00-24
%j 一年中的一天:001-366
%J 朱利安天数
%m 月:01-12
%M 分钟:00-59
%s 1970年1月1日以来的秒数
%S 秒:00-59
%w 0-6的星期几,星期日== 0
%W 一年中的第几周:00-53
%Y 年:0000-9999
%%

注意,所有其他日期和时间函数都可以用strftime()表示:

功能等效的strftime()
日期(...) strftime('%Y-%m-%d',...)
时间(...) strftime('%H:%M:%S',...)
约会时间(...) strftime('%Y-%m-%d%H:%M:%S',...)
十月节(...) strftime('%J',...)

提供strftime()以外的功能的唯一原因是为了方便和提高效率。

2.时间值

时间值可以采用以下任何一种格式,如下所示。该值通常是一个字符串,尽管在格式12的情况下可以是整数或浮点数。

  1. YYYY-MM-DD
  2. YYYY-MM-DD HH:MM
  3. YYYY-MM-DD HH:MM:SS
  4. YYYY-MM-DD HH:MM:SS.SSS
  5. YYYY-MM-DD T HH:MM
  6. YYYY-MM-DD T HH:MM:SS
  7. YYYY-MM-DD T HH:MM:SS.SSS
  8. 高度:毫米
  9. HH:MM:SS
  10. HH:MM:SS.SSS
  11. 现在
  12. DDDDDDDDDD

按照ISO-8601的要求,在格式5到7中,“ T”是分隔日期和时间的文字字符 。仅指定时间的格式8到10假定日期为2000-01-01。从使用中的sqlite3_vfs对象的xCurrentTime方法获得的格式11,字符串“ now”被转换为当前日期和时间。日期和时间函数的'now'参数对于同一sqlite3_step()调用中的多次调用始终返回完全相同的值。 使用世界标准时间(UTC)。格式12是 儒略日数字, 表示为整数或浮点值。

格式2到10可以可选地跟随一个时区指示符,形式为“ [+-] HH:MM ”或仅为“ Z ”。日期和时间函数在内部使用UTC或“ zulu”时间,因此“ Z”后缀为空。从指示的日期和时间中减去任何非零的“ HH:MM”后缀,以计算zulu时间。例如,以下所有时间值都是等效的:

2013-10-07 08:23:
19.120 2013-10-07T08:23:19.120Z
2013-10-07 04:23:19.120-04:00
2456572.84952685

在格式4、7和10中,小数秒数值SS.SSS可以在小数点后一位或多位数字。示例中仅显示了三位数字,因为只有前三位数字对结果有效,但是输入字符串的位数可以少于或多于三位,并且日期/时间功能仍将正确运行。同样,格式12显示为10个有效数字,但日期/时间函数实际上将接受表示儒略日数字所需的任意多或少的数字。

3.修饰符

时间值后可以跟零个或多个修改日期和/或时间的修饰符。每个修饰符都是一个应用于其左侧时间值的变换。修饰符从左到右应用;顺序很重要。可用的修饰符如下。

  1. NNN天
  2. NNN小时
  3. NNN分钟
  4. NNN.NNNN秒
  5. NNN月
  6. NNN年
  7. 月初
  8. 年初
  9. 一天的开始
  10. 工作日N
  11. 统一纪元
  12. 当地时间
  13. 世界标准时间

前六个修饰符(1到6)仅将指定的时间量添加到左侧参数所指定的日期和时间。修饰符名称末尾的's'字符是可选的。请注意,“±NNN月”的工作方式是将原始日期转换为YYYY-MM-DD格式,在MM月值中加上±NNN,然后对结果进行归一化。因此,例如,以“ +1个月”修改的数据2001-03-31最初产生2001-04-31,但是4月只有30天,因此日期被归一化为2001-05-01。当原始日期是a年的2月29日并且修饰符是±N年,其中N不是4的倍数时,会发生类似的效果。

“开始日期”修饰符(7到9)将日期向后移动到当前月,年或日的开始。

如果需要,“工作日”修饰符会将日期提前到工作日号为N的下一个日期。星期日为0,星期一为1,依此类推。如果日期已经在所需的工作日,则“工作日”修饰符将使日期保持不变。

“ unixepoch”修饰符(11)仅在紧随DDDDDDDDDD格式的时间值后才起作用。此修饰符使DDDDDDDDDD不再像通常那样解释为儒略日数,而是解释为 Unix时间-自1970年以来的秒数。如果“ unixepoch”修饰符不遵循DDDDDDDDDD形式的时间值,则表示自1970年以来的秒数,或者如果其他修饰符将“ unixepoch”修饰符与先前的DDDDDDDDDD分开,则该行为是不确定的。对于3.16.0(2017-01-02)之前的SQLite版本,“ unixepoch”修饰符仅适用于0000-01-01 00:00:00和5352-11-01 10:52:47之间的日期( -62167219200至106751991167)。

“ localtime”修饰符(12)假定其左侧的时间值位于世界协调时间(UTC)中,并调整该时间值以使其处于本地时间。如果“ localtime”遵循的时间不是UTC,则该行为是不确定的。“ utc”修饰符与“ localtime”相反。“ utc”假定其左侧的时间值位于本地时区,并将该时间值调整为UTC。如果左边的时间不在本地时间,则“ utc”的结果不确定。

4.例子

计算当前日期。

SELECT date('now');

计算当月的最后一天。

SELECT date('now','month of start','+ 1 month','-1 day');

给定unix时间戳1092941466,计算日期和时间。

SELECT datetime(1092941466,'unixepoch');

给定unix时间戳1092941466,计算日期和时间,并补偿您的本地时区。

SELECT datetime(1092941466,'unixepoch','localtime');

计算当前的unix时间戳。

SELECT strftime('%s','now');

计算自美国独立宣言签署以来的天数。

SELECT julianday('now')-julianday('1776-07-04');

计算自2004年某个特定时刻以来的秒数:

选择strftime('%s','now')-strftime('%s','2004-01-01 02:34:56');

计算当年10月的第一个星期二的日期。

SELECT date('now','year of start','+ 9 months','weekday 2');

计算以秒为单位的自unix纪元以来的时间(类似于strftime('%s','now'),但包括小数部分):

SELECT(julianday('now')-2440587.5)* 86400.0;

5.注意事项和错误

当地时间的计算在很大程度上取决于政客的心血来潮,因此很难在所有地区都获得正确的信息。在此实现中,标准C库函数localtime_r()用于协助计算本地时间。通常,localtime_r()C函数仅在1970年至2037年之间有效。对于此范围之外的日期,SQLite尝试将年份映射到该范围内的等效年份,进行计算,然后将年份映射回去。

这些功能仅适用于0000-01-01 00:00:00和9999-12-31 23:59:59之间的日期(儒略日编号1721059.5至5373484.5)。对于超出该范围的日期,这些函数的结果是不确定的。

非Vista Windows平台仅支持一组DST规则。Vista仅支持两个。因此,在这些平台上,历史DST计算将是不正确的。例如,在美国,DST规则于2007年更改。非Vista Windows平台也将新的2007 DST规则也应用到所有以前的年份。Vista的效果要好一些,可以使结果正确地追溯到1986年,当时规则也发生了变化。

所有内部计算均采用 公历 系统。还假设每天的持续时间精确为86400秒。