时间/日期函数和操作符

重要

本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。

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

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

日期/时间操作符

date + integerdate给日期加上天数date '2001-09-28' + 72001-10-05

date + intervaltimestamp为日期添加时间间隔date '2001-09-28' + interval '1 hour'2001-09-28 01:00:00

date + timetimestamp在日期中添加一天中的时间date '2001-09-28' + time '03:00'2001-09-28 03:00:00

interval + intervalinterval添加时间间隔interval '1 day' + interval '1 hour'1 day 01:00:00

timestamp + intervaltimestamp在时间戳中添加一个时间间隔timestamp '2001-09-28 01:00' + interval '23 hours'2001-09-29 00:00:00

time + intervaltime为时间添加时间间隔time '01:00' + interval '3 hours'04:00:00

- intervalinterval取否一个时间间隔- interval '23 hours'-23:00:00

date - dateinteger减去日期,生成经过的天数date '2001-10-01' - date '2001-09-28'3

date - integerdate从日期中减去天数date '2001-10-01' - 72001-09-24

date - intervaltimestamp从日期中减去时间间隔date '2001-09-28' - interval '1 hour'2001-09-27 23:00:00

time - timeinterval减去时间time '05:00' - time '03:00'02:00:00

time - intervaltime从时间中减去时间间隔time '05:00' - interval '2 hours'03:00:00

timestamp - intervaltimestamp从时间戳中减去时间间隔timestamp '2001-09-28 23:00' - interval '23 hours'2001-09-28 00:00:00

interval - intervalinterval减去时间间隔interval '1 day' - interval '1 hour'1 day -01:00:00

timestamp - timestampinterval减去时间戳(将24小时间隔转换为天,类似于justify_hours()timestamp '2001-09-29 03:00' - timestamp '2001-07-27 12:00'63 days 15:00:00

interval * double precisioninterval将时间间隔乘以数量interval '1 second' * 90000:15:00

interval '1 day' * 2121 days

interval '1 hour' * 3.503:30:00

interval / double precisioninterval用时间间隔除以数量

interval '1 hour' / 1.500:40:00

日期/时间函数

age ( timestamp, timestamp ) → interval减去参数,生成一个使用年和月,而不是只用日的“符号化”的结果

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

age ( timestamp ) → intervalcurrent_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_datedate当前日期

current_date2019-12-23

current_timetime with time zone一天中的当前时间

current_time14:39:53.662522-05

current_time ( integer ) → time with time zone

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

current_time(2)14:39:53.66-05

current_timestamptimestamp with time zone

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

current_timestamp2019-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_daysjustify_hours调整时间间隔; 通过额外的符号调整

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

localtimetime

一天中当前时间

localtime14:39:53.662522

localtime ( integer ) → time

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

localtime(0)14:39:53

localtimestamptimestamp

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

localtimestamp2019-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,除非startend相等,这种情况下它表示单个时间实例。例如这表示两个只有一个共同端点的时间段不重叠。

    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必须是一个类型 timestamptimeinterval的值表达式(类型为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');
    结果:2

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

    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对于单调增的域(epochjulianyearisoyeardecadecentury以及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是类型timestampinterval的值表达式(类型datetime的值都分别被自动转换成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 zoneinterval输入时,不能指定时区。 这些总是按表面值来处理

示例(假设当地时区为 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 zonetimestamp 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 zonetimestamp 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 zonetime 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_TIMECURRENT_TIMESTAMP传递带有时区的值;LOCALTIMELOCALTIMESTAMP传递的值不带时区。

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

一些例子:

    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

描述

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

语法

TZ_OFFSET({ char | SESSIONTIMEZONE | DBTIMEZONE})

参数解释

参数

说明

char

CHARVARCHAR2NCHARNVARCHAR2类型,为要转换的字符串。

返回类型

返回INTERVAL YEAR TO MONTH类型数据。

示例

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

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

TO_DSINTERVAL

描述

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

语法

TZ_OFFSET({ char | SESSIONTIMEZONE | DBTIMEZONE})

参数

参数

说明

char

CHARVARCHAR2NCHARNVARCHAR2类型,为要转换的字符串。

nlsparam

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

返回类型

返回INTERVAL DAY TO SECOND类型数据。

示例

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

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

TO_TIMESTAMP_TZ

描述

该函数将CHARVARCHAR2NCHARNVARCHAR2数据类型的char转换为TIMESTAMP WITH TIME ZONE数据类型的值。

语法

TZ_OFFSET({ char | SESSIONTIMEZONE | DBTIMEZONE})

参数

参数

说明

char

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

fmt

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

nlsparam

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

返回类型

返回TIMESTAMP WITH TIME ZONE类型数据。

示例

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

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

SYSTIMESTAMP

描述

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

语法

TZ_OFFSET({ char | SESSIONTIMEZONE | DBTIMEZONE})

返回类型

返回TIMESTAMP WITH TIME ZONE类型数据。

示例

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

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

SYSDATE

描述

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

语法

TZ_OFFSET({ char | SESSIONTIMEZONE | DBTIMEZONE})

返回类型

返回DATE类型数据。

示例

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

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

SYS_EXTRACT_UTC

描述

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

语法

TZ_OFFSET({ char | SESSIONTIMEZONE | DBTIMEZONE})

参数

参数

说明

datetime_with_timezone

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

返回类型

返回TIMESTAMP类型数据。

示例

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

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

SESSIONTIMEZONE

描述

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

语法

TZ_OFFSET({ char | SESSIONTIMEZONE | DBTIMEZONE})

返回类型

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

示例

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

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

NUMTOYMINTERVAL

描述

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

说明

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

语法

TZ_OFFSET({ char | SESSIONTIMEZONE | DBTIMEZONE})

参数

参数

说明

n

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

interval_unit

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

返回类型

返回INTERVAL YEAR TO MONTH类型数据。

示例

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

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

NUMTODSINTERVAL

描述

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

说明

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

语法

TZ_OFFSET({ char | SESSIONTIMEZONE | DBTIMEZONE})

参数

参数

说明

n

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

interval_unit

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

返回类型

返回INTERVAL DAY TO SECOND类型数据。

示例

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

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

NEXT_DAY

描述

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

说明

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

语法

TZ_OFFSET({ char | SESSIONTIMEZONE | DBTIMEZONE})

参数解释

参数

说明

date

DATE类型数据。

week

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

返回类型

返回DATE类型数据。

示例

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

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

NEW_TIME

描述

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

说明

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

语法

TZ_OFFSET({ char | SESSIONTIMEZONE | DBTIMEZONE})

参数

参数

说明

date

DATE类型数据。

timezone1

时区信息。

timezone2

时区信息。

返回类型

返回DATE类型数据。

示例

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

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

MONTHS_BETWEEN

描述

该函数返回date1date2之间的月数。

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

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

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

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

语法

TZ_OFFSET({ char | SESSIONTIMEZONE | DBTIMEZONE})

参数

参数

说明

date1

DATE类型数据。

date2

DATE类型数据。

返回类型

返回NUMBER类型数据。

示例

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

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

LOCALTIMESTAMP

描述

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

说明

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

  • LOCALTIMESTAMP返回TIMESTAMP值。

  • CURRENT_IMESTAMP则返回TIMESTAMPWITH TIME ZONE值。

语法

TZ_OFFSET({ char | SESSIONTIMEZONE | DBTIMEZONE})

参数

参数

说明

timestamp_precision

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

返回类型

返回TIMESTAMP类型数据。

示例

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

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

LAST_DAY

描述

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

语法

TZ_OFFSET({ char | SESSIONTIMEZONE | DBTIMEZONE})

参数

参数

说明

date

表示日期的DATE类型数据。

返回类型

返回DATE类型数据。

示例

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

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

ADD_MONTHS

描述

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

说明

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

语法

TZ_OFFSET({ char | SESSIONTIMEZONE | DBTIMEZONE})

参数

参数

说明

date

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

n

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

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

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

返回类型

返回DATE类型数据。

示例

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

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

FROM_TZ

描述

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

语法

TZ_OFFSET({ char | SESSIONTIMEZONE | DBTIMEZONE})

参数

参数

说明

timestamp_value

时间戳,为timestamp类型。

time_zone_value

时区信息。

返回类型

返回TIMESTAMP WITH TIME ZONE类型数据。

示例

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

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

EXTRACT(datetime)

描述

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

语法

TZ_OFFSET({ char | SESSIONTIMEZONE | DBTIMEZONE})

参数

参数

说明

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 TZ_OFFSET('pst8pdt') FROM DUAL;
 tz_offset 
-----------
 -07:00

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

DBTIMEZONE

描述

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

语法

TZ_OFFSET({ char | SESSIONTIMEZONE | DBTIMEZONE})

返回类型

返回varchar2数据类型。

示例

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

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

CURRENT_TIMESTAMP

描述

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

说明

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

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

  • LOCALTIMESTAMP返回TIMESTAMP类型值。

语法

TZ_OFFSET({ char | SESSIONTIMEZONE | DBTIMEZONE})

参数

参数

说明

precision

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

返回类型

返回TIMESTAMP WITH TIME ZONE类型数据。

示例

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

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

CURRENT_DATE

描述

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

语法

TZ_OFFSET({ char | SESSIONTIMEZONE | DBTIMEZONE})

返回类型

返回DATE类型数据。

示例

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

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