↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1
历史版本PostgreSQL 7.2 已于 2007 年 2 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

4.8. 日期/时间函数和操作符 #

表 4.17 列出了可用于 日期/时间值处理的函数。 表 4.16 图解了 基本算术 操作符(+、* 等)的行为。 格式化函数请参阅 第 4.7 节。你应当熟悉 日期/时间数据类型的背景信息(见第 3.5 节)。

下面描述的日期/时间操作符对涉及时区的类型和不涉及时区的类型 的行为类似。

表 4.16. 日期/时间操作符

名称 例子 结果
+ timestamp '2001-09-28 01:00' + interval '23 hours' timestamp '2001-09-29 00:00'
+ date '2001-09-28' + interval '1 hour' timestamp '2001-09-28 01:00'
+ time '01:00' + interval '3 hours' time '04:00'
- timestamp '2001-09-28 23:00' - interval '23 hours' timestamp '2001-09-28'
- date '2001-09-28' - interval '1 hour' timestamp '2001-09-27 23:00'
- time '05:00' - interval '2 hours' time '03:00'
- interval '2 hours' - time '05:00' time '03:00:00'
* interval '1 hour' * int '3' interval '03:00'
/ interval '1 hour' / int '3' interval '00:20'


日期/时间函数汇总如下,更多细节在后续小节中给出。

表 4.17. 日期/时间函数

名称 返回类型 描述 例子 结果
age(timestamp) interval 从今天减去 age(timestamp '1957-06-13') 43 years 8 mons 3 days
age(timestamp, timestamp) interval 参数相减 age('2001-04-10', timestamp '1957-06-13') 43 years 9 mons 27 days
current_date date 今天的日期;见下文    
current_time time 一天中的时间;见下文    
current_timestamp timestamp 日期和时间;见下文    
date_part(text, timestamp) double precision 获取子字段(等价于 extract);另见下文 date_part('hour', timestamp '2001-02-16 20:38:40') 20
date_part(text, interval) double precision 获取子字段(等价于 extract);另见下文 date_part('month', interval '2 years 3 months') 3
date_trunc(text, timestamp) timestamp 截断到指定精度;另见下文 date_trunc('hour', timestamp '2001-02-16 20:38:40') 2001-02-16 20:00:00+00
extract(field from timestamp) double precision 获取子字段;另见下文 extract(hour from timestamp '2001-02-16 20:38:40') 20
extract(field from interval) double precision 获取子字段;另见下文 extract(month from interval '2 years 3 months') 3
isfinite(timestamp) boolean 测试时间戳是否有限(既非无效也非无穷) isfinite(timestamp '2001-02-16 21:28:30') true
isfinite(interval) boolean 测试间隔是否有限 isfinite(interval '4 hours') true
now() timestamp 当前日期和时间(等价于 current_timestamp);见下文    
timeofday() text 当前日期和时间;见下文 timeofday() Wed Feb 21 17:01:13.000126 2001 EST
timestamp(date) timestamp date 转换为 timestamp timestamp(date '2000-12-25') 2000-12-25 00:00:00
timestamp(date, time) timestamp date 和 time 转换为 timestamp timestamp(date '1998-02-24',time '23:07') 1998-02-24 23:07:00


4.8.1. EXTRACT, date_part #

EXTRACT (field FROM source)

extract 函数从日期/时间值中 检索诸如年或小时这样的子字段。 source 是一个求值结果为 timestamp 或 interval 类型的值表达式。 (date 或 time 类型的表达式 会被转换为 timestamp,因此也可以 使用。)field 是一个标识符或 字符串,它选择从源值中提取哪个字段。 extract 函数返回 double precision 类型的值。 下面是有效的取值:

century

年份字段除以 100

SELECT EXTRACT(CENTURY FROM TIMESTAMP '2001-02-16 20:38:40');
结果:20

注意,century 字段的结果只是年份字段 除以 100,而不是把 1900 年代的大部分年份 归入二十世纪的传统定义。

day

(月中的)日字段(1 - 31)

SELECT EXTRACT(DAY FROM TIMESTAMP '2001-02-16 20:38:40');
结果:16
decade

年份字段除以 10

SELECT EXTRACT(DECADE FROM TIMESTAMP '2001-02-16 20:38:40');
结果:200
dow

星期几(0 - 6;星期日为 0)(仅用于 timestamp 值)

SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40');
结果:5
doy

一年中的第几天(1 - 365/366)(仅用于 timestamp 值)

SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40');
结果:47
epoch

对于 date 和 timestamp 值,是自 1970-01-01 00:00:00-00 以来的秒数(结果可能为负。); 对于 interval 值,是该间隔中的 总秒数

SELECT EXTRACT(EPOCH FROM TIMESTAMP '2001-02-16 20:38:40');
结果:982352320

SELECT EXTRACT(EPOCH FROM INTERVAL '5 days 3 hours');
结果:442800
hour

小时字段(0 - 23)

SELECT EXTRACT(HOUR FROM TIMESTAMP '2001-02-16 20:38:40');
结果:20
microseconds

秒字段(包括小数部分)乘以 1 000 000。注意这包括完整的秒数。

SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5');
结果:28500000
millennium

年份字段除以 1000

SELECT EXTRACT(MILLENNIUM FROM TIMESTAMP '2001-02-16 20:38:40');
结果:2

注意,millennium 字段的结果只是年份字段 除以 1000,而不是把 1900 年代的年份 归入第二个千年的传统定义。

milliseconds

秒字段(包括小数部分)乘以 1000。注意这包括完整的秒数。

SELECT EXTRACT(MILLISECONDS FROM TIME '17:12:28.5');
结果:28500
minute

分钟字段(0 - 59)

SELECT EXTRACT(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40');
结果:38
month

对于 timestamp 值,是一年中的月份数 (1 - 12);对于 interval 值, 是月数模 12(0 - 11)

SELECT EXTRACT(MONTH FROM TIMESTAMP '2001-02-16 20:38:40');
结果:2

SELECT EXTRACT(MONTH FROM INTERVAL '2 years 3 months');
结果:3

SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months');
结果:1
quarter

该日所在的一年中的季度(1 - 4)(仅用于 timestamp 值)

SELECT EXTRACT(QUARTER FROM TIMESTAMP '2001-02-16 20:38:40');
结果:1
second

秒字段(包括小数部分)(0 - 59[4])

SELECT EXTRACT(SECOND FROM TIMESTAMP '2001-02-16 20:38:40');
结果:40

SELECT EXTRACT(SECOND FROM TIME '17:12:28.5');
结果:28.5
timezone_hour

时区偏移量的小时部分。

timezone_minute

时区偏移量的分钟部分。

week

从 timestamp 值计算 该日所在一年中的 周数。根据定义 (ISO 8601),一年的第一周 包含该年的 1 月 4 日。(ISO 的周从星期一开始。)换句话说,一年的 第一个星期四在该年的第 1 周。

SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40');
结果:7
year

年份字段

SELECT EXTRACT(YEAR FROM TIMESTAMP '2001-02-16 20:38:40');
结果:2001

extract函数主要的用途是做计算性处理。对于用于显示的日期/时间值格式化,参阅第 4.7 节。

date_part 函数仿照传统 Ingres 中与 SQL 函数 extract 等价的函数建模:

date_part('field', source)

注意这里的 field 值需要 是字符串。date_part 的有效字段取值与 extract 的相同。

SELECT date_part('day', TIMESTAMP '2001-02-16 20:38:40');
Result: 16

SELECT date_part('hour', INTERVAL '4 hours 3 minutes');
Result: 4

4.8.2. date_trunc #

date_trunc函数在概念上和用于数字的trunc函数类似。

date_trunc('field', source)

source 是一个 timestamp 类型的值表达式(date 和 time 类型的值会被自动转换)。 field 选择把时间戳值 截断到哪种精度。返回值的类型是 timestamp,其中所有低于所选字段的字段 都被置为零(日和月则置为一)。

field 的有效值有:

microseconds
milliseconds
second
minute
hour
day
month
year
decade
century
millennium
SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40');
结果:2001-02-16 20:00:00+00

SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40');
结果:2001-01-01 00:00:00+00

4.8.3. 当前日期/时间 #

可以使用下面的函数获得当前日期和/或 时间:

CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_TIME ( precision )
CURRENT_TIMESTAMP ( precision )

CURRENT_TIME 和 CURRENT_TIMESTAMP 可以选择性地接受 一个精度参数,它使结果被舍入 到那么多位小数。如果没有精度参数, 结果将给出完整的可用精度。

注意

在PostgreSQL 7.2 之前,精度参数是没有实现的,结果总是以整数秒给出。

注意

SQL99 标准要求这些函数在 不带精度参数时不写任何圆括号。从 PostgreSQL 7.2 开始,可以写一个 空的圆括号对,但这已被废弃,在未来的版本中可能被 移除。

SELECT CURRENT_TIME;
14:39:53.662522-05

SELECT CURRENT_DATE;
2001-12-23

SELECT CURRENT_TIMESTAMP;
2001-12-23 14:39:53.662522-05

SELECT CURRENT_TIMESTAMP(2);
2001-12-23 14:39:53.66-05

now()是PostgreSQL中与CURRENT_TIMESTAMP等价的传统函数。

还有 timeofday(),由于历史 原因它返回一个文本字符串而不是 timestamp 值:

SELECT timeofday();
 Sat Feb 17 19:07:32.000126 2001 EST

十分重要的是要认识到 CURRENT_TIMESTAMP 及相关函数返回的都是 当前事务开始时的时间;在事务运行期间它们的值不 增长。但 timeofday() 返回实际的当前时间。

所有日期/时间数据类型还接受特殊的字面值 now 来指定当前日期和时间。因此, 下面三个都返回相同的结果:

SELECT CURRENT_TIMESTAMP;
SELECT now();
SELECT TIMESTAMP 'now';

注意

在创建表时指定 DEFAULT 值不要使用第三种形式。系统会在 解析常量时立即把 now 转换为 timestamp,因此在需要默认值时, 使用的将是建表时刻的时间!前两种 形式在默认值被使用之前不会被求值, 因为它们是函数调用。因此它们会给出 在插入行时取默认值的期望 行为。



[4] 如果操作系统实现了闰秒则为 60

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。