跳到主要内容

日期/时间函数和操作符

日期时间运算首先要辨别类型:date 表示日历日期,time 表示一天内的时间,timestamp 不带时区,timestamptz 表示时间点并按会话时区显示。以下示例使用 PostgreSQL。

加减与间隔​

SELECT date '2025-03-08' + 7; -- 2025-03-15
SELECT timestamp '2025-03-08 10:00' + interval '2 hours';
SELECT timestamp '2025-03-09 10:00' - timestamp '2025-03-08 10:00';
-- 1 day

日期加整数按天计算;两个时间戳相减得到 interval。interval '1 month' 不是固定 30 天:月末、闰年和夏令时会改变结果。date 加 time 得到 timestamp,类型参与运算后可能改变。

提取与分桶​

SELECT extract(year FROM timestamp '2025-03-08 10:15'); -- 2025
SELECT date_trunc('month', timestamp '2025-03-08 10:15');
-- 2025-03-01 00:00:00

extract 获取年、月、日、星期、epoch 等字段;date_trunc 把更低精度部分归零,适合按月/小时分组。date_bin(interval '15 minutes', event_at, timestamp '2000-01-01') 可按固定步长及给定原点分桶,步长不能包含月或更大单位。时间范围筛选通常用原列上的半开区间,避免对索引列逐行执行 date_trunc。

当前时间与时区​

SELECT current_date, current_timestamp, now();
SELECT timestamp '2025-03-08 10:00' AT TIME ZONE 'Asia/Shanghai';

now() 和 current_timestamp 是事务开始时间;statement_timestamp() 是当前语句开始时间;clock_timestamp() 返回实际调用时刻,单条语句中也可变化。timestamp AT TIME ZONE zone 把本地钟面时间解释成一个时间点;timestamptz AT TIME ZONE zone 则得到该时区的无时区钟面时间,方向相反。

存储真实事件时间优先考虑 timestamptz,并明确展示时区。遇到夏令时跳变的本地时间可能不存在或重复;固定长度的“24 小时”和日历上的“一天”不总是相同。