4.7. 日期/时间函数 #
表 4.14列出了可用于日期/时间值处理的函数。基本的算术操作符(+、* 等)也可用。格式化函数请参阅第 4.6 节。你应当熟悉日期/时间数据类型的背景信息(见第 3.4 节)。
表 4.14. 日期/时间函数
| 名称 | 返回类型 | 描述 | 示例 | 结果 |
|---|---|---|---|---|
| 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 to timestamp | timestamp(date '2000-12-25') | 2000-12-25 00:00:00 |
| timestamp(date, time) | timestamp | 把日期和时间转换为 timestamp | timestamp(date '1998-02-24',time '23:07') | 1998-02-24 23:07:00 |
4.7.1. EXTRACT, date_part #
EXTRACT (fieldFROMsource)
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 以来的秒数(结果可能为负。);对于interval值,是该间隔中的总秒数SELECT EXTRACT(EPOCH FROM TIMESTAMP '2001-02-16 20:38:40'); 结果:
982352320SELECT 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'); 结果:
2SELECT EXTRACT(MONTH FROM INTERVAL '2 years 3 months'); 结果:3SELECT 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[3])
SELECT EXTRACT(SECOND FROM TIMESTAMP '2001-02-16 20:38:40'); 结果:
40SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); 结果:28.5- 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.6 节。
date_part 函数仿照传统
Ingres 中与
SQL 函数 extract 等价的函数建模:
date_part('field', source)
注意这里的 field 值需要是字符串。date_part 的有效字段取值与
extract 的相同。
SELECT date_part('day', TIMESTAMP '2001-02-16 20:38:40');
结果:16
SELECT date_part('hour', INTERVAL '4 hours 3 minutes')
结果:44.7.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.7.3. 当前日期/时间 #
可以使用下面的函数获得当前日期和/或时间:
CURRENT_TIME CURRENT_DATE CURRENT_TIMESTAMP
注意,由于内部实现的要求,这些函数必须不带圆括号使用。
SELECT CURRENT_TIME;19:07:32SELECT CURRENT_DATE;2001-02-17SELECT CURRENT_TIMESTAMP;2001-02-17 19:07:32-05
函数 now() 是 Postgres 中 CURRENT_TIMESTAMP 的传统等价形式。
还有 timeofday(),它返回的当前时间比
CURRENT_TIMESTAMP 一族具有更高的精度:
SELECT timeofday(); Sat Feb 17 19:07:32.000126 2001 EST
timeofday() 使用操作系统调用
gettimeofday(2),其分辨率可以好到微秒(取决于你的平台);而其他函数从 time(2) 获取时间,大多数平台上分辨率最多为 1 秒。
十分重要的是要认识到
CURRENT_TIMESTAMP 及相关函数返回的都是当前事务开始时的时间;在事务运行期间它们的值不增长。但
timeofday() 返回实际的当前时间。
所有日期/时间数据类型还接受特殊的字面值
now 来指定当前日期和时间。因此,下面三个都返回相同的结果:
SELECT CURRENT_TIMESTAMP; SELECT now(); SELECT TIMESTAMP 'now';
注意
在创建表时指定 DEFAULT 值不要使用第三种形式。系统会在解析常量时立即把 now 转换为
timestamp,因此在需要默认值时,使用的将是建表时刻的时间!前两种形式在默认值被使用之前不会被求值,因为它们是函数调用。因此它们会给出在插入行时取默认值的期望行为。