更新时间:2026-01-22 GMT+08:00

时间和日期截取函数

date_part(text, timestamp | interval)

date_part函数用于从一个日期时间表达式(timestamp或interval)中提取指定的部分(text),等效于extract(field from timestamp)函数。

语法:

date_part('field', source)
  • source,必须是一个timestamp、time或interval类型的值表达式(类型为date的表达式转换为timestamp,因此也可以用)。
  • field,是一个标识符或者字符串,它指定从源数据中抽取的时间部分。field的取值见表1

返回值类型:double precision

示例:

获取指定日期的小时数。

1
2
3
4
5
SELECT date_part('hour', timestamp '2001-02-16 20:38:40');
 date_part 
-----------
        20
(1 row)

从时间间隔2 years 3 months中提取月份部分。

1
2
3
4
5
SELECT date_part('month', interval '2 years 3 months');
 date_part 
-----------
         3
(1 row)

date_trunc(text, timestamp with time zone | timestamp without time zone | interval)

描述:将时间日期数据截断到指定的(text)精度。

text支持microseconds、milliseconds、second、minute、hour、day、week、month、quarter、year、decade、century、millennium。

返回值类型:timestamp with time zone、timestamp without time zone、interval

示例:

将输入的时间截断到小时。

1
2
3
4
5
SELECT date_trunc('hour', timestamp '2025-02-16 20:38:40');
     date_trunc
---------------------
 2025-02-16 20:00:00
(1 row)

将输入的时间截断到天。

1
2
3
4
5
SELECT date_trunc('day', timestamptz'2025-02-16 20:38:40+08');
       date_trunc
------------------------
 2025-02-16 00:00:00-05
(1 row)

将输入的时间截断到月。

1
2
3
4
5
SELECT date_trunc('month', timestamp '2025-02-16 20:38:40');
     date_trunc
---------------------
 2025-02-01 00:00:00
(1 row)

将输入时间戳截断至一个季度的第一天。

1
2
3
4
5
SELECT DATE_TRUNC('quarter', TIMESTAMP '20250430 04:05:06.789');
     date_trunc
---------------------
 2025-04-01 00:00:00
(1 row)

截取当前月的1号12点。

1
2
3
4
5
SELECT date_trunc('month',now()) +interval '12h';
        ?column?
------------------------
 2025-09-01 12:00:00-04
(1 row)

截取当日的9点。

1
2
3
4
5
SELECT date_trunc('day',now()) + interval '9h';
        ?column?
------------------------
 2025-09-22 09:00:00-04
(1 row)

截取今年的第一天。

1
2
3
4
5
SELECT date_trunc('year',CURRENT_DATE);
       date_trunc
------------------------
 2025-01-01 00:00:00-05
(1 row)

trunc(timestamp)

描述:默认按天截取。

返回值类型:timestamp

示例:

1
2
3
4
SELECT trunc(timestamp '2001-02-16 20:38:40');                                                                                                                                                                   trunc
---------------------
2001-02-16 00:00:00
(1 row)

extract(field from timestamp | time | interval)

extract函数用于从日期时间的表达式中提取指定的时间部分,例如提取年份、月份、小时等。

语法:

EXTRACT(field FROM source)
  • source,必须是一个timestamp、time或interval类型的值表达式(类型为date的表达式转换为timestamp,因此也可以用)。
  • field,是一个标识符或者字符串,它指定从源数据中抽取的时间部分。field的取值见表1

extract函数返回值类型:double precision

表1 field的取值

field

含义

用法示例

提取结果

century

世纪

从给定的时间戳中提取世纪部分数值:

1
SELECT EXTRACT(CENTURY FROM TIMESTAMP '2000-12-16 12:21:13');

第一个世纪从0001-01-01 00:00:00 AD开始。这个定义适用于所有使用阳历的国家。没有0世纪,直接从公元前1世纪到公元1世纪。

返回结果如下:

1
2
3
date_part 
-----------
        20

millennium

千年

从指定的时间戳中提取千年部分的数值:

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

20世纪(19xx年)里面的年份在第二个千年里。第三个千年从2001年1月1日零时开始。

返回结果如下:

1
2
3
4
 date_part 
-----------
         3
(1 row)

decade

十年

从指定的时间戳中提取十年编号的数值:

1
SELECT EXTRACT(DECADE FROM TIMESTAMP '2001-02-16 20:38:40');

返回结果如下:

1
2
3
4
 date_part 
-----------
       200
(1 row)

year

从指定的时间戳中提取年份部分。

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

返回结果如下:

1
2
3
4
 date_part 
-----------
      2001
(1 row)

quarter

季度

从指定的时间戳中提取日期所在的季度(1~4个季度)。

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

返回结果如下:

1
2
3
4
 date_part 
-----------
         1
(1 row)

month

月份

  • 从指定的时间戳中提取月份部分。
    如果source为timestamp,表示一年里的月份数(1~12)。
    1
    SELECT EXTRACT(MONTH FROM TIMESTAMP '2001-02-16 20:38:40');
    
  • 从时间间隔中提取月份部分。
    如果source为interval,表示月的数目,自动将月份超过12的部分转换为年份,剩余部分作为月份。
    1
    SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months');
    
  • 返回结果如下:
    1
    2
    3
    4
     date_part 
    -----------
             2
    (1 row)
    
  • 返回结果如下:
    1
    2
    3
    4
     date_part 
    -----------
             1
    (1 row)
    

week

遵循ISO 8601标准:一年的第一个星期四在第一周;每周从星期一开始,到星期日结束;范围:1-53。

获取目标日期是在一年中的第几周。

1
SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40');

返回结果如下:

1
2
3
4
 date_part 
-----------
         7
(1 row)

day

  • 从指定的时间戳中提取天(一个月中的第几天)的部分。
    如果source为timestamp,表示月份里的日期(1~31)。
    1
    SELECT EXTRACT(DAY FROM TIMESTAMP '2001-02-16 20:38:40');
    
  • 从时间间隔中提取天数部分。
    如果source为interval,表示天数。
    1
    SELECT EXTRACT(DAY FROM INTERVAL '40 days 1 minute');
    
  • 返回结果如下:
    1
    2
    3
    4
     date_part 
    -----------
            16
    (1 row)
    
  • 返回结果如下:
    1
    2
    3
    4
     date_part 
    -----------
            40
    (1 row)
    

hour

小时

从指定的时间戳中提取小时部分(0~23)。

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

返回结果如下:

1
2
3
4
 date_part 
-----------
        20
(1 row)

minute

分钟

从指定的时间戳中提取分钟部分。

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

返回结果如下:

1
2
3
4
 date_part 
-----------
        38
(1 row)

second

从指定的时间戳中提取秒部分(包含小数部分)。

1
SELECT EXTRACT(SECOND FROM TIME '17:12:28.5');

返回结果如下:

1
2
3
4
 date_part 
-----------
      28.5
(1 row)

milliseconds

毫秒

从指定的时间戳中提取毫秒部分。返回的是整个秒字段的毫秒表示,即秒部分(包括小数秒)乘以 1000。

1
SELECT EXTRACT(MILLISECONDS FROM TIME '17:12:28.5');

返回结果如下:

1
2
3
4
 date_part 
-----------
     28500
(1 row)

microseconds

微秒

从指定的时间戳中提取微秒部分。返回的是整个秒字段的微秒表示,即秒部分(包括小数秒)乘以 1,000,000。

1
SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5');

返回结果如下:

1
2
3
4
 date_part 
-----------
  28500000
(1 row)

epoch

纪元以来的天数

  • 如果source为timestamp with time zone,表示自1970-01-01 00:00:00-00 UTC以来的秒数(结果可能是负数);
    1
    SELECT EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40.12-08');
    
  • 如果source为date和timestamp,表示自1970-01-01 00:00:00-00当地时间以来的秒数;
  • 如果source为interval,表示时间间隔的总秒数。
    1
    SELECT EXTRACT(EPOCH FROM INTERVAL '5 days 3 hours');
    
将epoch值转换为时间戳的方法。
1
2
3
4
5
SELECT TIMESTAMP WITH TIME ZONE 'epoch' + 982384720.12 * INTERVAL '1 second' AS RESULT;
          result          
---------------------------
 2001-02-17 12:38:40.12+08
(1 row)

返回结果如下:

1
2
3
4
  date_part   
--------------
 982384720.12
(1 row)

返回结果如下:

1
2
3
4
 date_part 
-----------
    442800
(1 row)

doy

一年中的第几天

获取指定时间戳中的日期是一年中的第几天(1~365/366)。

1
SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40');

返回结果如下:

1
2
3
4
 date_part 
-----------
        47
(1 row)

isodow

一周的第几天

获取指定时间戳中的日期是一周中的第几天(1~7,星期一为1,星期天为7)。

1
SELECT EXTRACT(ISODOW FROM TIMESTAMP '2001-02-18 20:38:40');

返回结果如下:

1
2
3
4
 date_part 
-----------
         7
(1 row)

dow

一周中的第几天,周日为0

获取指定时间戳中的日期是一周中的第几天(0~6,星期天为0,星期六为6)

1
SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40');

返回结果如下:

1
2
3
4
 date_part 
-----------
         5
(1 row)

isoyear

ISO 8601标准年

获取指定日期在ISO 8601标准下的年份(不适用于interval)

每个带有星期一开始的周中包含1月4日的ISO年,所以在年初的1月或12月下旬的ISO年可能会不同于阳历的年。可参见week的描述。

1
SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-01');
1
SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02');

返回结果如下:

1
2
3
4
 date_part 
-----------
      2005
(1 row)

返回结果如下:

1
2
3
4
 date_part 
-----------
      2006
(1 row)

timezone

与UTC的时区偏移量

与UTC的时区偏移量,单位为秒。正数对应UTC东边的时区,负数对应UTC西边的时区。

1
SELECT EXTRACT(timezone FROM TIMETZ '17:12:28');

返回结果如下:

1
2
3
4
 date_part
-----------
   28800
(1 row)

timezone_hour

时区偏移量的小时部分

从带时区的时间值中提取时区偏移量的小时部分。

1
SELECT EXTRACT(timezone_hour FROM TIMETZ '17:12:28');

返回结果如下:

1
2
3
4
 date_part
-----------
       8
(1 row)

timezone_minute

时区偏移量的分钟部分

从带时区的时间值中提取时区偏移量的分钟部分。

1
SELECT EXTRACT(timezone_minute FROM TIMETZ '17:12:28');

返回结果如下:

1
2
3
4
 date_part
-----------
         0
(1 row)