时间/日期函数和操作符

更新时间:
复制为 MD 格式

本文介绍了 PolarDB PostgreSQL 版(兼容 Oracle) 支持的时间、日期函数和操作符。

说明

所有下文描述的接受 time timestamp 输入的函数和操作符实际上都有两种变体:一种接受 time with time zone timestamp with time zone , 另外一种接受 time without time zone 或者 timestamp without time zone 。为了简化,这些变体未独立展示。此外, + `` 操作符都是可交换的操作符对(例如, date+integer integer+date );本文仅展示其中一个。

日期/时间操作符

语法

描述

示例

date + integer date

给日期加上天数。

date '2001-09-28' + 7 2001-10-05

date + interval timestamp

为日期添加时间间隔。

date '2001-09-28' + interval '1 hour' 2001-09-28 01:00:00

date + time timestamp

在日期中添加一天中的时间。

date '2001-09-28' + time '03:00' 2001-09-28 03:00:00

interval + interval interval

添加时间间隔。

interval '1 day' + interval '1 hour' 1 day 01:00:00

timestamp + interval timestamp

在时间戳中添加一个时间间隔。

timestamp '2001-09-28 01:00' + interval '23 hours' 2001-09-29 00:00:00

time + interval time

为时间添加时间间隔。

time '01:00' + interval '3 hours' 04:00:00

- interval interval

为一个时间间隔取否。

- interval '23 hours' -23:00:00

date - date integer

减去日期,生成经过的天数。

date '2001-10-01' - date '2001-09-28' 3

date - integer date

从日期中减去天数。

date '2001-10-01' - 7 2001-09-24

date - interval timestamp

从日期中减去时间间隔。

date '2001-09-28' - interval '1 hour' 2001-09-27 23:00:00

time - time interval

减去时间。

time '05:00' - time '03:00' 02:00:00

time - interval time

从时间中减去时间间隔。

time '05:00' - interval '2 hours' 03:00:00

timestamp - interval timestamp

从时间戳中减去时间间隔。

timestamp '2001-09-28 23:00' - interval '23 hours' 2001-09-28 00:00:00

interval - interval interval

减去时间间隔。

interval '1 day' - interval '1 hour' 1 day -01:00:00

timestamp - timestamp interval

减去时间戳(将 24 小时间隔转换为天,类似于 justify_hours() )。

timestamp '2001-09-29 03:00' - timestamp '2001-07-27 12:00' 63 days 15:00:00

interval * double precision interval

将时间间隔乘以数量。

  • interval '1 second' * 900 00:15:00

  • interval '1 day' * 21 21 days

  • interval '1 hour' * 3.5 03:30:00

interval / double precision interval

用时间间隔除以数量。

interval '1 hour' / 1.5 00:40:00

日期/时间函数

语法

描述

示例

age ( timestamp , timestamp ) → interval

减去参数,生成一个使用年和月,而不是只用日的“符号化”的结果。

age(timestamp '2001-04-10', timestamp '1957-06-13') 43 years 9 mons 27 days

age ( timestamp ) → interval

current_date 减去参数(在午夜)。

age(timestamp '1957-06-13') 62 years 6 mons 10 days

clock_timestamp ( ) → timestamp with time zone

当前日期和时间(在语句执行期间变化)。

clock_timestamp() 2019-12-23 14:39:53.662522-05

current_date date

当前日期。

current_date 2019-12-23

current_time time with time zone

一天中的当前时间。

current_time 14:39:53.662522-05

current_time ( integer ) → time with time zone

一天中的当前时间,有限精度。

current_time(2) 14:39:53.66-05

current_timestamp timestamp with time zone

当前日期和时间(当前事务的开始)。

current_timestamp 2019-12-23 14:39:53.662522-05

current_timestamp ( integer ) → timestamp with time zone

当前日期和时间(当前事务的开始),有限精度。

current_timestamp(0) 2019-12-23 14:39:53-05

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

date_trunc ( text , timestamp with time zone , text ) → timestamp with time zone

在规定的时区中截断到指定的精度。

date_trunc('day', timestamptz '2001-02-16 20:38:40+00', 'Asia/Shanghai') 2001-02-16 16:00:00 +00

date_trunc ( text , interval ) → interval

截断到指定的精度。

date_trunc('hour', interval '2 days 3 hours 40 minutes') 2 days 03: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 ( date ) → boolean

测试有限日期(不是+/-无限)。

isfinite(date '2001-02-16') true

isfinite ( timestamp ) → boolean

测试有限时间戳(不是+/-无限)

isfinite(timestamp 'infinity') false

isfinite ( interval ) → boolean

测试有限时间间隔 (当前总是为真)。

isfinite(interval '4 hours') true

justify_days ( interval ) → interval

调整间隔,使得 30 天时间周期表示为月。

justify_days(interval '35 days') 1 mon 5 days

justify_hours ( interval ) → interval

调整时间间隔,使得 24 小时时间周期表示为日。

justify_hours(interval '27 hours') 1 day 03:00:00

justify_interval ( interval ) → interval

使用 justify_days justify_hours 调整时间间隔,通过额外的符号调整。

justify_interval(interval '1 mon -1 hour') 29 days 23:00:00

localtime time

一天中当前时间。

localtime 14:39:53.662522

localtime ( integer ) → time

一天中的当前时间,有限精度。

localtime(0) 14:39:53

localtimestamp timestamp

当前日期和时间(当前事务的开始)。

localtimestamp 2019-12-23 14:39:53.662522

localtimestamp ( integer ) → timestamp

当前日期和时间(当前事务的开始),有限精度。

localtimestamp(2) 2019-12-23 14:39:53.66

make_date ( year int , month int , day int ) → date

从年、月和日字段创建日期。

make_date(2013, 7, 15) 2013-07-15

make_interval ( [ years int [, months int [, weeks int [, days int [, hours int [, mins int [, secs double precision ]]]]]]] ) → interval

从年、月、周、日、小时、分钟和秒字段创建时间间隔,每个字段默认为 0。

make_interval(days => 10) 10 days

make_time ( hour int , min int , sec double precision ) → time

从小时、分钟和秒字段创建时间。

make_time(8, 15, 23.5) 08:15:23.5

make_timestamp ( year int , month int , day int , hour int , min int , sec double precision ) → timestamp

从年、月、日、小时、分钟和秒字段创建时间戳。

make_timestamp(2013, 7, 15, 8, 15, 23.5) 2013-07-15 08:15:23.5

make_timestamptz ( year int , month int , day int , hour int , min int , sec double precision [, timezone text ] ) → timestamp with time zone

从年,月,日,小时,分钟和秒字段结合时区创建时间戳;如果没有指定 timezone ,则使用当前时区。

make_timestamptz(2013, 7, 15, 8, 15, 23.5) 2013-07-15 08:15:23.5+01

now ( ) → timestamp with time zone

当前日期和时间(当前事务的开始)。

now() 2019-12-23 14:39:53.662522-05

statement_timestamp ( ) → timestamp with time zone

当前日期和时间(当前语句的开始)。

statement_timestamp() 2019-12-23 14:39:53.662522-05

timeofday ( ) → text

当前的日期和时间 (类似 clock_timestamp , 但是采用 text 字符串)。

timeofday() Mon Dec 23 14:39:53.662522 2019 EST

transaction_timestamp ( ) → timestamp with time zone

当前日期和时间(当前事务的开始)。

transaction_timestamp() 2019-12-23 14:39:53.662522-05

to_timestamp ( double precision ) → timestamp with time zone

Unix 纪元转换为带时区的时间戳(从 1970-01-01 00:00:00+00 开的秒)。

to_timestamp(1284352323) 2010-09-13 04:32:03+00

除了这些函数以外,还支持 SQL 操作符 OVERLAPS

    (start1, end1) OVERLAPS (start2, end2)
    (start1, length1) OVERLAPS (start2, length2)

这个表达式在两个时间域(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面, OVERLAPS 会自动地把较早的值作为起点。每一个时间段被认为是表示半开的间隔 start <= time < end ,除非 start end 相等,这种情况下它表示单个时间实例。例如这表示两个只有一个共同端点的时间段不重叠。

    SELECT (DATE '2001-02-16', DATE '2001-12-21') OVERLAPS
           (DATE '2001-10-30', DATE '2002-10-30');
    结果:true
    SELECT (DATE '2001-02-16', INTERVAL '100 days') OVERLAPS
           (DATE '2001-10-30', DATE '2002-10-30');
    结果:false
    SELECT (DATE '2001-10-29', DATE '2001-10-30') OVERLAPS
           (DATE '2001-10-30', DATE '2001-10-31');
    结果:false
    SELECT (DATE '2001-10-30', DATE '2001-10-30') OVERLAPS
           (DATE '2001-10-30', DATE '2001-10-31');
    结果:true

当把一个 interval 值添加到 timestamp with time zone 上(或从中减去)时, 天的部分会按照指定的天数增加或减少 timestamp with time zone 的日期,保持一天中相同的时间。 对于横跨夏令时的变化(当会话的时区被设置为可识别 DST 的时区时),这意味着 interval '1 day' 并不一定等于 interval '24 hours' 。 例如,当会话的时区设置为 America/Denver 时:

    SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '1 day';
    Result: 2005-04-03 12:00:00-06
    SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours';
    Result: 2005-04-03 13:00:00-06

发生此情况是因为夏令时在 America/Denver 时区的 2005-04-03 02:00:00 的时间发生更改而跳过了一个小时。

注意 age 返回的 月数 域可能有歧义,因为不同的月份有不同的天数。 本数据库的方法是当计算部分月数时,采用两个日期中较早的月。例如: age('2004-06-01', '2004-04-30') 使用 4 月份得到 1 mon 1 day ,而用 5 月份时会得到 1 mon 2 days ,因为 5 月有 31 天,而 4 月只有 30 天。

日期和时间戳的减法也可能会很复杂。执行减法的一种概念上很简单的方法是,使用 EXTRACT(EPOCH FROM ...) 把每个值都转换成秒数,然后执行减法, 这样会得到两个值之间的 数。这种方法将会适应每个月中天数、 时区改变和夏令时调整。使用“ - ”操作符的日期或时间戳减法会返回值之间的天数(24 小时)以及时/分/秒,也会做同样的调整。 age 函数会返回年、月、日以及时/分/秒,执行按域的减法,然后对负值域进行调整。下面的查询展示了这些方法的不同。例子中的结果由 timezone = 'US/Eastern' 产生,这使得两个使用的日期之间存在着夏令时的变化:

    SELECT EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') -
           EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00');
    Result: 10537200
    SELECT (EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') -
            EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00'))
            / 60 / 60 / 24;
    Result: 121.958333333333
    SELECT timestamptz '2013-07-01 12:00:00' - timestamptz '2013-03-01 12:00:00';
    Result: 121 days 23:00:00
    SELECT age(timestamptz '2013-07-01 12:00:00', timestamptz '2013-03-01 12:00:00');
    Result: 4 mons

EXTRACT, date_part

    EXTRACT(field FROM source)

extract 函数从日期/时间值中抽取子域,例如年或者小时等。 source 必须是一个类型 timestamp time interval 的值表达式(类型为 date 的表达式将被造型为 timestamp ,并且因此也可以被同样使用)。 field 是一个标识符或者字符串,它指定从源值中抽取的域。 extract 函数返回类型为 double precision 的值。 下列值是有效的域名字 ∶

century 世纪

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

第一个世纪从 0001-01-01 00:00:00 AD 开始, 尽管那时候人们还不知道这是第一个世纪。这个定义适用于所有使用格里高利历法的国家。其中没有 0 世纪,我们直接从公元前 1 世纪到公元 1 世纪。 如果你认为这个不合理,那么请把抱怨发给:罗马圣彼得教堂,梵蒂冈,教皇收。

day 对于 timestamp 值,是(月份)里的日域(1–31);对于 interval 值,是日数。

    SELECT EXTRACT(DAY FROM TIMESTAMP '2001-02-16 20:38:40');
    结果:16
    SELECT EXTRACT(DAY FROM INTERVAL '40 days 1 minute');
    结果:40

decade 年份域除以 10。

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

dow 一周中的日,从周日( 0 )到周六( 6 )。

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

请注意, extract 的一周中的日和 to_char(..., 'D') 函数不同。

doy 一年的第几天(1–365/366)。

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

epoch 对于 timestamp with time zone 值, 是自 1970-01-01 00:00:00 UTC 以来的秒数(结果可能是负数); 对于 date and timestamp 值,是自本地时间 1970-01-01 00:00:00 以来的描述;对于 interval 值,它是时间间隔的总秒数。

    SELECT EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40.12-08');
    结果:982384720.12
    SELECT EXTRACT(EPOCH FROM INTERVAL '5 days 3 hours');
    结果:442800

不能用 to_timestamp 把一个 epoch 值转换回成时间戳:

    SELECT to_timestamp(982384720.12);
    Result: 2001-02-17 04:38:40.12+00

hour 小时域(0–23)。

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

isodow 一周中的日,从周一( 1 )到周日( 7 )。

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

除了周日,这和 dow 相同。这符合 ISO 8601 中一周中的日的编号。

isoyear 日期所落在的 ISO 8601 周编号的年(不适用于间隔)

    SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-01');
    结果:2005
    SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02');
    结果:2006

每一个 ISO 8601 周编号的年都开始于包含 1 4 日的那一周的周一,在早的 1 月或迟的 12 月中 ISO 年可能和格里高利年不同。更多信息见 week 域。

这个域不能用于 PostgreSQL 8.3 之前的版本。

microseconds 秒域,包括小数部分,乘以 1,000,000。请注意它包括全部的秒。

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

millennium 千年。

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

19xx 的年份在第二个千年里。第三个千年从 2001 1 1 日开始。

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');
    SELECT EXTRACT(MONTH FROM INTERVAL '2 years 3 months');
    SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months');
    结果:1

quarter 该天所在的该年的季度(1–4)。

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

second 秒字段,包括任何小数秒。

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

timezone UTC 的时区偏移,以秒记。正数对应 UTC 东边的时区,负数对应 UTC 西边的时区(从技术上来看,本数据库不使用 UTC,因为其中不处理闰秒)。

timezone_hour 时区偏移的小时部分。

timezone_minute 时区偏移的分钟部分。

week 该天在所在的 ISO 8601 周编号的年份里是第几周。根据定义, 一年的第一周包含该年的 1 4 日并且 ISO 周从星期一开始。换句话说,一年的第一个星期四在第一周。

ISO 周编号系统中,早的 1 月的日期可能位于前一年的第五十二或者第五十三周,而迟的 12 月的日期可能位于下一年的第一周。例如, 2005-01-01 位于 2004 年的第五十三周,并且 2006-01-01 位于 2005 年的第五十二周,而 2012-12-31 位于 2013 年的第一周。我们推荐把 isoyear 域和 week 一起使用来得到一致的结果。

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

year 年份域。要记住这里没有 0 AD ,所以从 AD 年里抽取 BC 年应该小心处理。

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

当输入值为+/-Infinity 时, extract 对于单调增的域( epoch julian year isoyear decade century 以及 millennium )返回+/-Infinity。对于其他域返回 NULL。本数据库 9.6 之前的版本对所有输入无穷的情况都返回零。

extract 函数主要的用途是做计算性处理。

在传统的 Ingres 上建模的 date_part 函数等价于 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');
    结果:4

date_trunc

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

    date_trunc(field, source [, time_zone ])

source 是类型 timestamp interval 的值表达式(类型 date time 的值都分别被自动转换成 timestamp , timestamp with time zone ,或者 interval )。 field 选择对输入值选用什么样的精度进行截断。返回的值是 timestamp , timestamp with time zone ,类型或者所有小于选定的精度的域都设置为零(或者一,对于日期和月份)的 interval

field 的有效值是:

microseconds

milliseconds

second

minute

hour

day

week

month

quarter

year

decade

century

millennium

当输入值的类型为 timestamp with time zone 时。截断是针对特定时区进行的。 例如,截断为 day ,产生的值是该区域的午夜。 默认情况下,截断是在以下方面进行的到当前的 TimeZone 设置,但在当前的可以提供可选的 time_zone 参数。以指定不同的时区。

当处理 timestamp without time zone interval 输入时,不能指定时区。 这些总是按表面值来处理。

示例(假设当地时区为 America/New_York ):

    SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40');
    结果:2001-02-16 20:00:00
    SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40');
    结果:2001-01-01 00:00:00
    SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00');
    Result: 2001-02-16 00:00:00-05
    SELECT date_trunc('day', timestamptz '2001-02-16 20:38:40+00', 'Asia/Shanghai');
    Result: 2001-02-16 16:00:00 +00
    SELECT date_trunc('hour', INTERVAL '3 days 02:47:33');
    Result: 3 days 02:00:00

AT TIME ZONE

AT TIME ZONE 把时间戳 without 时区转换成时间戳 with 时区或者反过来,并且把 time with time zone 值转换成不同的时区。AT TIME ZONE 变体表 9.33 展示了它的变体。

AT TIME ZONE 变体

语法

描述

示例

timestamp without time zone AT TIME ZONE zone timestamp with time zone

将给定的时间戳 without 时区转换为时间戳 with 时区,假设给定的值在指定的时区内。

timestamp '2001-02-16 20:38:40' at time zone 'America/Denver' 2001-02-17 03:38:40+00

timestamp with time zone AT TIME ZONE zone timestamp without time zone

将给定的时间戳 with 时区转换为时间戳 without 时区,因为时间将出现在该时区中。

timestamp with time zone '2001-02-16 20:38:40-05' at time zone 'America/Denver' 2001-02-16 18:38:40

time with time zone AT TIME ZONE zone time with time zone

将给定的时间 with 时区转换为新的时区。由于没有提供日期,这将使用指定目的区域的当前活动 UTC 偏移量。

time with time zone '05:34:17-05' at time zone 'UTC' 10:34:17+00

在这些表达式里,我们需要的时区 zone 可以指定为文本值(例如, 'America/Los_Angeles' )或者一个间隔 (例如, INTERVAL '-08:00' )。时间区间只适用于与 UTC 有固定偏移量的区域,因此在实践中并不常见。

例子 (假设当前 TimeZone 设置为 America/Los_Angeles ):

    SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'America/Denver';
    Result: 2001-02-16 19:38:40-08
    SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'America/Denver';
    Result: 2001-02-16 18:38:40
    SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 'America/Chicago';
    Result: 2001-02-16 05:38:40

第一个例子给缺少时区的值加上了时区,并且显示了使用当前 TimeZone 设置的值。 第二个例子把带有时区值的时间戳移动到指定的时区,并且返回不带时区的值。 这允许存储和显示不同于当前 TimeZone 设置的值。第三个例子把东京时间转换成芝加哥时间。

函数 timezone``(``zone``, ``timestamp``) 等效于 SQL 兼容的结构 timestamp`` AT TIME ZONE ``zone

当前日期/时间

本数据库提供了许多返回当前日期和时间的函数。这些 SQL 标准的函数全部都按照当前事务的开始时刻返回值:

    CURRENT_DATE
    CURRENT_TIME
    CURRENT_TIMESTAMP
    CURRENT_TIME(precision)
    CURRENT_TIMESTAMP(precision)
    LOCALTIME
    LOCALTIMESTAMP
    LOCALTIME(precision)
    LOCALTIMESTAMP(precision)

CURRENT_TIME CURRENT_TIMESTAMP 传递带有时区的值; LOCALTIME LOCALTIMESTAMP 传递的值不带时区。

CURRENT_TIME CURRENT_TIMESTAMP LOCALTIME LOCALTIMESTAMP 可以有选择地接受一个精度参数, 该精度导致结果的秒域被园整为指定小数位。如果没有精度参数,结果将被给予所能得到的全部精度。

一些例子:

    SELECT CURRENT_TIME;
    结果: 14:39:53.662522-05
    SELECT CURRENT_DATE;
    结果: 2019-12-23
    SELECT CURRENT_TIMESTAMP;
    结果: 2019-12-23 14:39:53.662522-05
    SELECT CURRENT_TIMESTAMP(2);
    结果: 2019-12-23 14:39:53.66-05
    SELECT LOCALTIMESTAMP;
    结果: 2019-12-23 14:39:53.662522

因为这些函数全部都按照当前事务的开始时刻返回结果,所以它们的值在事务运行的整个期间内都不改变。 我们认为这是一个特性:目的是为了允许一个事务在“当前”时间上有一致的概念, 这样在同一个事务里的多个修改可以保持同样的时间戳。

重要

许多其它数据库系统可能会更频繁地推进这些值。

本数据库同样也提供了返回当前语句开始时间的函数, 它们会返回函数被调用时的真实当前时间。这些非 SQL 标准的函数列表如下:

    transaction_timestamp()
    statement_timestamp()
    clock_timestamp()
    timeofday()
    now()

transaction_timestamp() 等价于 CURRENT_TIMESTAMP ,但是其命名清楚地反映了它的返回值。 statement_timestamp() 返回当前语句的开始时刻(更准确的说是收到客户端最后一条命令的时间)。 statement_timestamp() transaction_timestamp() 在一个事务的第一条命令期间返回值相同,但是在随后的命令中却不一定相同。 clock_timestamp() 返回真正的当前时间,因此它的值甚至在同一条 SQL 命令中都会变化。 timeofday() 是一个有历史原因的本数据库函数。和 clock_timestamp() 相似, timeofday() 也返回真实的当前时间,但是它的结果是一个格式化的 text 串,而不是 timestamp with time zone 值。 now() 是本数据库的一个传统,等效于 transaction_timestamp()

所有日期/时间类型还接受特殊的文字值 now ,用于指定当前的日期和时间(重申,被解释为当前事务的开始时刻)。 因此,下面三个都返回相同的结果:

    SELECT CURRENT_TIMESTAMP;
    SELECT now();
    SELECT TIMESTAMP 'now';  -- 但请参阅下面的提示

提示

当指定以后要计算的值时,不要使用第三种形式,例如在表列的 DEFAULT 子句中。 系统将在分析这个常量的时候把 now 转换为一个 timestamp , 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用缺省值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。

延时执行

下面的这些函数可以用于让服务器进程延时执行:

    pg_sleep ( double precision )
    pg_sleep_for ( interval )
    pg_sleep_until ( timestamp with time zone )

pg_sleep 使当前会话的进程休眠,直到过去给定的秒数。可以指定几分之一秒的延迟。 pg_sleep_for 是一个方便的函数,允许将睡眠时间指定为时间间隔。 pg_sleep_until 是一个方便的函数,用于需要特定的唤醒时间。例如:

    SELECT pg_sleep(1.5);
    SELECT pg_sleep_for('5 minutes');
    SELECT pg_sleep_until('tomorrow 03:00');

注意

有效的休眠时间间隔精度是与平台相关的,通常 0.01 秒是通用值。休眠延迟将至少持续指定的时长, 也有可能由于服务器负荷而比指定的时间长。特别地, pg_sleep_until 并不保证能刚好在指定的时刻被唤醒,但它不会在比指定时刻早的时候醒来。

警告

请确保在调用 pg_sleep 或者其变体时,你的会话没有持有不必要的锁。否则其它会话可能必须等待你的休眠会话,因而减慢整个系统速度。

TZ_OFFSET

描述

该函数返回与基于语句输入参数相对应的时区偏移量。

语法

TZ_OFFSET({ char | SESSIONTIMEZONE | DBTIMEZONE})

参数

参数

说明

char

字符串类型, 参数可以是有效的时区名称或者从 UTC 开始的时区偏移量。

SESSIONTIMEZONE

当前会话时区。

DBTIMEZONE

数据库时区。

返回类型

返回 VARCHAR 类型数据。

示例

SELECT TZ_OFFSET('pst8pdt') FROM DUAL;
 tz_offset 
-----------
 -07:00
SELECT TZ_OFFSET(SESSIONTIMEZONE) FROM DUAL;
 tz_offset 
-----------
 +00:00

TO_YMINTERVAL

描述

该函数将 CHAR VARCHAR2 NCHAR NVARCHAR2 数据类型的字符串转换为 INTERVAL YEAR TO MONTH 值。

语法

TO_YMINTERVAL(char)

参数解释

参数

说明

char

CHAR VARCHAR2 NCHAR NVARCHAR2 类型,为要转换的字符串。

返回类型

返回 INTERVAL YEAR TO MONTH 类型数据。

示例

SELECT TO_YMINTERVAL('2016-1') FROM DUAL;
 to_yminterval
---------------
 +2016-01

TO_DSINTERVAL

描述

该函数将 CHAR VARCHAR2 NCHAR NVARCHAR2 数据类型的字符串转换为 INTERVAL DAY TO SECOND 值。

语法

TO_DSINTERVAL(char[, nlsparam])

参数

参数

说明

char

CHAR VARCHAR2 NCHAR NVARCHAR2 类型,为要转换的字符串。

nlsparam

可选项,此函数中可以指定的唯一有效 nlsparam NLS_NUMERIC_CHARACTERS,采用以下形式,NLS_NUMERIC_HARACTERS=“dg”,其中 d g 分别表示十进制字符和组分隔符。两个字符都不能是空格。

返回类型

返回 INTERVAL DAY TO SECOND 类型数据。

示例

SELECT TO_DSINTERVAL('1 1:1:00') FROM DUAL;
 to_dsinterval
---------------
 +01 01:01:00

TO_TIMESTAMP_TZ

描述

该函数将 CHAR VARCHAR2 NCHAR NVARCHAR2 数据类型的 char 转换为 TIMESTAMP WITH TIME ZONE 数据类型的值。

语法

TO_TIMESTAMP_TZ(char,[fmt],['nlsparam'])

参数

参数

说明

char

用于转换为 TIMESTAMP WITH TIME ZONE 类型数据的字符串。

fmt

用于指定 TIMESTAMP WITH TIME ZONE 类型结果的格式。

nlsparam

可选项,用来指定返回的月份和日期所使用的语言。

返回类型

返回 TIMESTAMP WITH TIME ZONE 类型数据。

示例

SELECT TO_TIMESTAMP_TZ('2020-02-11 11:00:00 -8:00','YYYY-MM-DD HH:MI:SS TZH:TZM') FROM DUAL;
     to_timestamp_tz
-------------------------
 2020-02-11 19:00:00 +00

SYSTIMESTAMP

描述

该函数返回数据库所在系统的系统日期,包括小数秒和时区。

语法

SYSTIMESTAMP

返回类型

返回 TIMESTAMP WITH TIME ZONE 类型数据。

示例

SELECT SYSTIMESTAMP FROM DUAL;
    systimestamp
---------------------
 2023-06-21 08:41:24

SYSDATE

描述

该函数返回为数据库所在的操作系统设置的当前日期和时间。返回值的数据类型为 DATE ,返回的格式取决于 NLS_DATE_format 初始化参数的值。该函数不需要参数。

语法

SYSDATE

返回类型

返回 DATE 类型数据。

示例

SELECT SYSDATE FROM DUAL;
  sysdate
------------
 2023-06-21

SYS_EXTRACT_UTC

描述

该函数从带有时区偏移量或时区区域名称的日期时间值中提取标准的 UTC 时间(协调世界时,前身为格林尼治标准时间)。

语法

SYS_EXTRACT_UTC(datetime_with_timezone)

参数

参数

说明

datetime_with_timezone

带有时区偏移量或时区区域名称的日期时间值

返回类型

返回 TIMESTAMP 类型数据。

示例

SELECT SYS_EXTRACT_UTC(TIMESTAMP '2020-02-11 11:30:00.00 +08:00') FROM DUAL;
   sys_extract_utc
---------------------
 2020-02-11 11:30:00

SESSIONTIMEZONE

描述

该函数返回当前会话的时区。,具体取决于用户在最近的 ALTER session 语句中指定会话时区值的方式。

语法

SESSIONTIMEZONE

返回类型

返回类型字符串,时区偏移量(格式为 “[+|]TZH:TZM” )或者或时区区域名称。

示例

SELECT SESSIONTIMEZONE FROM DUAL;
 sessiontimezone
-----------------
 UTC

NUMTOYMINTERVAL

描述

该函数将 n 转换为 INTERVAL YEAR TO MONTH 类型结果。

说明

interval_unit 不区分大小写。忽略括号内的前导值和尾随值。默认情况下,返回的精度为 9。

语法

NUMTODSINTERVAL(n,interval_unit)

参数

参数

说明

n

NUMBER 类型数据或者是可以隐式转换为 NUMBER 的表达式。

interval_unit

CHAR VARCHAR2 NCHAR NVARCHAR2 数据类型, interval_unit 的值指定 n 的单位,需要时可以解析为'YEAR'、'MONTH'之一的字符串。

返回类型

返回 INTERVAL YEAR TO MONTH 类型数据。

示例

SELECT numtoyminterval('3.123456789','year') FROM DUAL;
 numtoyminterval
-----------------
 +03-01

NUMTODSINTERVAL

描述

该函数将 n 转换为 INTERVAL DAY TO SECOND 类型结果。

说明

interval_unit 不区分大小写。忽略括号内的前导值和尾随值。默认情况下,返回的精度为 9。

语法

NUMTODSINTERVAL(n,interval_unit)

参数

参数

说明

n

NUMBER 类型数据或者是可以隐式转换为 NUMBER 的表达式。

interval_unit

CHAR VARCHAR2 NCHAR NVARCHAR2 数据类型, interval_unit 的值指定 n 的单位,需要时可以解析为'DAY'、'HOUR'、'MINUTE'、'SECOND'之一的字符串。

返回类型

返回 INTERVAL DAY TO SECOND 类型数据。

示例

SELECT NUMTODSINTERVAL('3.123456789','hour') FROM DUAL;
  numtodsinterval
--------------------
 +00 03:07:24.44444

NEXT_DAY

描述

该函数返回用字符命名的第一个工作日的日期,该日期晚于输入参数 date 。无论输入参数 date 的数据类型如何,返回类型始终为 DATE 类型。参数 char 必须是会话的日期语言中的一周中的某一天,可以是全名或缩写。所需的最小字母数是缩写版本中的字母数。有效缩写后面的任何字符都将被忽略。

说明

返回值具有与输入参数 date 相同的时、分和秒。

语法

NEXT_DAY(date,week)

参数解释

参数

说明

date

DATE 类型数据。

week

表示星期值的字符串,包括 SUNDAY、MONDAY 等。

返回类型

返回 DATE 类型数据。

示例

SELECT NEXT_DAY('2003-08-01', 'TUESDAY') FROM DUAL;
  next_day
------------
 2003-08-05

NEW_TIME

描述

date timezone1 时区下的日期和时间时,该函数返回 timezone2 时区下的日期和时间。无论日期的数据类型如何,返回类型始终为 DATE

说明

在使用此函数之前,必须将 NLS_DATE_FORMAT 参数设置为显示 24 小时时间。

语法

NEW_TIME(date,timezone1,timezone2)

参数

参数

说明

date

DATE 类型数据。

timezone1

时区信息。

timezone2

时区信息。

返回类型

返回 DATE 类型数据。

示例

SELECT NEW_TIME(TO_DATE('11-10-09 01:23:45', 'MM-DD-YY HH24:MI:SS'), 'GMT','EST') ndt FROM DUAL;
---------------------
 2009-11-09 20:23:45

MONTHS_BETWEEN

描述

该函数返回 date1 date2 之间的月数。

说明
  • 如果 date1 晚于 date2 ,则结果为正。

  • 如果 date1 早于 date2 ,则结果为负数。

如果 date1 date2 是一个月的同一天,或者是两个月的最后一天,则结果总是一个整数。

否则,将根据 31 天的月份计算结果的小数部分,并考虑时间分量 date1 date2 的差异。

语法

MONTHS_BETWEEN(date1,date2)

参数

参数

说明

date1

DATE 类型数据。

date2

DATE 类型数据。

返回类型

返回 NUMBER 类型数据。

示例

SELECT MONTHS_BETWEEN(to_date ('2003/01/01', 'yyyy/mm/dd'), to_date('2003/03/14', 'yyyy/mm/dd')) FROM DUAL;
  months_between
-------------------
 -2.41935483870968

LOCALTIMESTAMP

描述

该函数以数据类型 TIMESTAMP 的值返回会话时区中的当前日期和时间。

说明

此函数与 CURRENT_TIMESTAMP 之间的区别在于:

  • LOCALTIMESTAMP 返回 TIMESTAMP 值。

  • CURRENT_IMESTAMP 则返回 TIMESTAMPWITH TIME ZONE 值。

语法

LOCALTIMESTAMP [(timestamp_precision)]

参数

参数

说明

timestamp_precision

int 类型数据,指定小数点后秒的位数。

返回类型

返回 TIMESTAMP 类型数据。

示例

SELECT LOCALTIMESTAMP(6) FROM DUAL;
      localtimestamp
----------------------------
2023-06-21 06:10:30.322893

LAST_DAY

描述

该函数返回包含日期的月份的最后一天的日期。无论日期的数据类型如何,返回类型始终为 DATE

语法

LAST_DAY(date)

参数

参数

说明

date

表示日期的 DATE 类型数据。

返回类型

返回 DATE 类型数据。

示例

SELECT LAST_DAY('2000-02-01') FROM DUAL;
  last_day
------------
 2000-02-29

ADD_MONTHS

描述

该函数返回日期 date 加上 n 个月后的日期值。

说明

由于每个月的天数不同,当 date 是一个月中的最后一天时,函数返回计算后所得月份的最后一天。例如,用 ADD_MONTHS 计算 2020 年 3 月 31 日一个月前的日期,返回 2020 年 2 月 29 日。

语法

ADD_MONTHS(date, n)

参数

参数

说明

date

指定日期。该参数为 DATE 数据类型。

n

整数或可以转换为一个整数的任意值。 NUMBER 数据类型。

  • 如果 n 的值为负数,则返回日期 date 基础上 n 个月前的日期值。

  • 如果 n 的值为正数,则返回日期 date 基础上 n 个月后的日期值。

返回类型

返回 DATE 类型数据。

示例

SELECT add_months ('2003-08-10', 3) FROM DUAL;
 add_months
------------
 2003-11-10

FROM_TZ

描述

FROM_TZ 将时间戳值和时区转换为 TIMESTAMP WITH TIME ZONE 值。 time_zone_value 是格式为“TZH:TZM”的字符串,或者是返回可选 TZD 格式的 TZR 字符串的字符表达式。

语法

FROM_TZ (timestamp_value,time_zone_value)

参数

参数

说明

timestamp_value

时间戳,为 timestamp 类型。

time_zone_value

时区信息。

返回类型

返回 TIMESTAMP WITH TIME ZONE 类型数据。

示例

SELECT FROM_TZ(TIMESTAMP '2000-03-28 08:00:00', '3:00') FROM DUAL;
         from_tz
-------------------------
 2000-03-28 05:00:00 +00

EXTRACT(datetime)

描述

该函数用于返回某个时间类型数据中提取的指定部分的值。

语法

EXTRACT(char FROM datetime)

参数

参数

说明

char

可以为 YEAR、MONTH、DAY、HOUR、MINUTE、SECOND、TIMEZONE_HOUR、TIMEZONE_MINUTE、TIMEZONE_REGION、TIMEZONE_ABBR 等,分别用于指定提取年、月、日、时、分、秒、时区时、时区分、时区秒、时区名称、时区名称缩写等。

datetime

DATE、TIMESTAMP、INTERVAL 等时间数据类型。

返回类型

  • char TIMEZONE_REGION 或者 TIMEZONE_ABBR 时,返回 VARCHAR2 数据类型。

  • char 为其他字符串时,返回 NUMBER 数据类型。

示例

SELECT
EXTRACT(YEAR FROM DATE '2020-05-26 13:30:25.575401') "YEAR",
EXTRACT(MONTH FROM DATE '2020-05-26 13:30:25.575401') "MONTH",
EXTRACT(DAY FROM DATE '2020-05-26 13:30:25.575401') "DAY" FROM DUAL;
 YEAR | MONTH | DAY
------+-------+-----
 2020 |     5 |  26
SELECT
EXTRACT(HOUR FROM TIME '13:30:25.575401') "HOUR",
EXTRACT(MINUTE FROM TIME '13:30:25.575401') "MINUTE",
EXTRACT(SECOND FROM TIME '13:30:25.575401') "SECOND",
EXTRACT(MICROSECOND FROM TIME '13:30:25.575401') "MICROSECOND" FROM DUAL;
 HOUR | MINUTE |  SECOND   | MICROSECOND
------+--------+-----------+-------------
   13 |     30 | 25.575401 |    25575401

DBTIMEZONE

描述

该函数用于返回数据库时区的值,返回值是时区偏移量,格式为”[+|-]TZH:TZM“的字符类型或者时区名称。

语法

DBTIMEZONE

返回类型

返回 varchar2 数据类型。

示例

SELECT DBTIMEZONE FROM DUAL;
 dbtimezone
------------
 GMT

CURRENT_TIMESTAMP

描述

该函数以 TIMESTAMP WITH TIME ZONE 数据类型的值返回当前会话时区的当前日期和时间。

说明

此函数与 LOCALTIMESTAMP 之间的区别在于:

  • CURRENT_TIMESTAMP 返回 TIMESTAMP WITH TIME ZONE 类型值。

  • LOCALTIMESTAMP 返回 TIMESTAMP 类型值。

语法

CURRENT_TIMESTAMP[(precision)]

参数

参数

说明

precision

可选项,用于指定秒小数位的精度,取整数值,默认为 6

返回类型

返回 TIMESTAMP WITH TIME ZONE 类型数据。

示例

SELECT CURRENT_TIMESTAMP(4) FROM DUAL;
  current_timestamp
------------------------------
 2023-06-20 08:34:13.3174 +00

CURRENT_DATE

描述

该函数返回当前会话所在时区的当前日期。

语法

CURRENT_DATE

返回类型

返回 DATE 类型数据。

示例

SELECT CURRENT_DATE FROM DUAL;
 current_date
--------------
 2023-06-20