在 SQLite 中,日期和时间 使用 内置函数 处理,不依赖操作系统时区,默认使用 UTC 存储。
支持灵活的 字符串、数值、函数混合 操作,格式非常强大。
一、SQLite 时间存储类型(推荐)
| 类型 | 说明 | 推荐 |
|---|---|---|
TEXT | '2025-11-07 09:26:00'(ISO8601) | 推荐 |
REAL | Julian Day(天数) | 内部计算 |
INTEGER | Unix 时间戳(秒) | 跨语言 |
最佳实践:用
TEXT存 ISO8601 格式,人类可读 + 排序正确
CREATE TABLE events (
id INTEGER PRIMARY KEY,
name TEXT,
created_at TEXT DEFAULT CURRENT_TIMESTAMP
);
二、核心时间函数
| 函数 | 说明 | 示例 |
|---|---|---|
CURRENT_TIMESTAMP | 当前 UTC 时间 | '2025-11-07 01:26:00' |
CURRENT_TIME | 当前时间 | '01:26:00' |
CURRENT_DATE | 当前日期 | '2025-07-07' |
DATETIME('now') | 等同 CURRENT_TIMESTAMP | |
JULIANDAY() | 儒略日(浮点) | 2461372.5 |
UNIXEPOCH() | Unix 时间戳 | 1730942760 |
三、时间修饰符(Modifiers)—— 强大!
可对时间进行 加减、时区、格式化:
SELECT DATETIME('now', '+8 hours'); -- 新加坡时间
SELECT DATETIME('now', 'localtime'); -- 本地时间(+08)
SELECT DATE('now', '-7 days'); -- 7天前
SELECT DATETIME('2025-11-07 09:26:00', '+1 month');
常用修饰符
| 修饰符 | 效果 |
|---|---|
'+8 hours' | 加8小时 |
'localtime' | 转为本地时间(推荐 SG 用户) |
'utc' | 转为 UTC |
'start of day' | 当天 00:00:00 |
'start of month' | 当月 1号 00:00 |
'-3 days' | 减3天 |
四、格式化输出:STRFTIME()
STRFTIME(格式, 时间)
| 格式 | 含义 | 示例 |
|---|---|---|
%Y | 年(4位) | 2025 |
%m | 月 | 11 |
%d | 日 | 07 |
%H | 小时(24) | 09 |
%M | 分钟 | 26 |
%S | 秒 | 00 |
%w | 星期(0=日) | 5 |
%j | 一年第几天 | 311 |
示例
-- 今天是星期几?
SELECT STRFTIME('%w', 'now'); -- 5(周五)
-- 格式化:2025年11月07日
SELECT STRFTIME('%Y年%m月%d日', 'now', 'localtime');
-- 本月第一天
SELECT STRFTIME('%Y-%m-01', 'now');
五、时间计算 & 比较
-- 插入新加坡时间
INSERT INTO events (name, created_at)
VALUES ('Login', DATETIME('now', 'localtime'));
-- 查询最近7天
SELECT * FROM events
WHERE created_at >= DATETIME('now', '-7 days', 'localtime');
-- 按天分组统计
SELECT
DATE(created_at, 'localtime') AS day,
COUNT(*) AS count
FROM events
GROUP BY day;
六、时区处理(SG 用户必看)
SQLite 默认 UTC,但你可以用 localtime:
-- 插入:自动转为 UTC 存储
INSERT INTO events (created_at)
VALUES (DATETIME('now', 'localtime')); -- 显示 +08,实际存 UTC
-- 查询:转为新加坡时间显示
SELECT
name,
DATETIME(created_at, 'localtime') AS sg_time
FROM events;
推荐:存 UTC,显本地
七、时间差计算(JULIANDAY 或 STRFTIME)
-- 两个时间相差天数
SELECT JULIANDAY('2025-11-07') - JULIANDAY('2025-11-01'); -- 6
-- 相差小时
SELECT
(JULIANDAY(end_time) - JULIANDAY(start_time)) * 24 AS hours_diff
FROM tasks;
八、实用查询示例
1. 今天、昨天、本周、本月
-- 今天
WHERE DATE(created_at, 'localtime') = DATE('now', 'localtime')
-- 昨天
WHERE DATE(created_at, 'localtime') = DATE('now', '-1 day', 'localtime')
-- 本周(周一开始)
WHERE DATE(created_at, 'localtime', 'weekday 1', '-6 days')
BETWEEN DATE('now', 'localtime', 'weekday 1', '-6 days')
AND DATE('now', 'localtime')
-- 本月
WHERE STRFTIME('%Y-%m', created_at, 'localtime') = STRFTIME('%Y-%m', 'now', 'localtime')
2. 按时间段分组
-- 按小时统计
SELECT
STRFTIME('%Y-%m-%d %H:00', created_at, 'localtime') AS hour,
COUNT(*)
FROM events
GROUP BY hour;
-- 按天
SELECT DATE(created_at, 'localtime') AS day, COUNT(*) FROM events GROUP BY day;
3. 年龄计算
-- 用户年龄(岁)
SELECT
name,
(STRFTIME('%Y', 'now') - STRFTIME('%Y', birth_date))
- (STRFTIME('%m%d', 'now') < STRFTIME('%m%d', birth_date)) AS age
FROM users;
九、最佳实践(SG 用户)
-- 1. 建表默认本地时间
CREATE TABLE logs (
id INTEGER PRIMARY KEY,
action TEXT,
created_at TEXT DEFAULT (DATETIME('now', 'localtime'))
);
-- 2. 查询统一用 localtime
SELECT *, DATETIME(created_at, 'localtime') FROM logs;
-- 3. 索引加速时间查询
CREATE INDEX idx_logs_created ON logs(created_at);
十、快速参考表
| 需求 | SQL |
|---|---|
| 当前新加坡时间 | DATETIME('now', 'localtime') |
| 7天前 | DATETIME('now', '-7 days', 'localtime') |
| 当天 00:00 | DATE('now', 'localtime', 'start of day') |
| 格式化 | STRFTIME('%Y-%m-%d %H:%M', time, 'localtime') |
| 本月数据 | STRFTIME('%Y-%m', created_at, 'localtime') = STRFTIME('%Y-%m', 'now', 'localtime') |
完整示例:事件日志系统
-- 建表
CREATE TABLE events (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INT,
action TEXT,
created_at TEXT DEFAULT (DATETIME('now', 'localtime'))
);
CREATE INDEX idx_events_time ON events(created_at);
-- 插入
INSERT INTO events (user_id, action) VALUES (123, 'login');
-- 查询今天
SELECT * FROM events
WHERE DATE(created_at) = DATE('now', 'localtime');
-- 按天统计
SELECT
DATE(created_at) AS day,
COUNT(*) AS events
FROM events
GROUP BY day
ORDER BY day DESC;
总结:SQLite 时间处理黄金法则
| 法则 | 说明 |
|---|---|
| 存 UTC,显本地 | 用 localtime 转换 |
| 用 TEXT + ISO8601 | '2025-11-07 09:26:00' |
| 建索引加速 | CREATE INDEX ON table(created_at) |
用 STRFTIME 分组 | 按年月日统计 |
用 JULIANDAY 计算差 | 精确到秒 |
需要我帮你:
- 生成按周/月统计的 SQL?
- 把 Unix 时间戳转本地时间?
- 自动插入带时区的日志系统?
把你的表结构或需求发我!