⌘+k ctrl+k
1.3 (稳定版)
搜索快捷键 cmd + k | ctrl + k
带时区时间戳函数

本节介绍用于检查和操作TIMESTAMP WITH TIME ZONE(或 TIMESTAMPTZ)值的函数和运算符。另请参阅相关的TIMESTAMP 函数

时区支持由内置的ICU 扩展提供。

在以下示例中,当前时区假定为America/Los_Angeles,并使用格里高利历。

内置带时区的时间戳函数

下表显示了TIMESTAMPTZ值可用的标量函数。由于这些函数不涉及分箱或显示,它们始终可用。

名称 描述
current_timestamp 当前日期和时间(当前事务开始时)。
get_current_timestamp() 当前日期和时间(当前事务开始时)。
greatest(timestamptz, timestamptz) 两个时间戳中较晚的一个。
isfinite(timestamptz) 如果带时区的时间戳是有限的,则返回true,否则返回false。
isinf(timestamptz) 如果带时区的时间戳是无限的,则返回true,否则返回false。
least(timestamptz, timestamptz) 两个时间戳中较早的一个。
now() 当前日期和时间(当前事务开始时)。
timetz_byte_comparable(timetz) TIME WITH TIME ZONE转换为UBIGINT排序键。
to_timestamp(double) 将自纪元以来的秒数转换为带时区的时间戳。
transaction_timestamp() 当前日期和时间(当前事务开始时)。

current_timestamp

描述 当前日期和时间(当前事务开始时)。
示例 current_timestamp
结果 2022-10-08 12:44:46.122-07

get_current_timestamp()

描述 当前日期和时间(当前事务开始时)。
示例 get_current_timestamp()
结果 2022-10-08 12:44:46.122-07

greatest(timestamptz, timestamptz)

描述 两个时间戳中较晚的一个。
示例 greatest(TIMESTAMPTZ '1992-09-20 20:38:48', TIMESTAMPTZ '1992-03-22 01:02:03.1234')
结果 1992-09-20 20:38:48-07

isfinite(timestamptz)

描述 如果带时区的时间戳是有限的,则返回true,否则返回false。
示例 isfinite(TIMESTAMPTZ '1992-03-07')
结果 true

isinf(timestamptz)

描述 如果带时区的时间戳是无限的,则返回true,否则返回false。
示例 isinf(TIMESTAMPTZ '-infinity')
结果 true

least(timestamptz, timestamptz)

描述 两个时间戳中较早的一个。
示例 least(TIMESTAMPTZ '1992-09-20 20:38:48', TIMESTAMPTZ '1992-03-22 01:02:03.1234')
结果 1992-03-22 01:02:03.1234-08

now()

描述 当前日期和时间(当前事务开始时)。
示例 now()
结果 2022-10-08 12:44:46.122-07

timetz_byte_comparable(timetz)

描述 TIME WITH TIME ZONE转换为UBIGINT排序键。
示例 timetz_byte_comparable('18:18:16.21-07:00'::TIMETZ)
结果 2494691656335442799

to_timestamp(double)

描述 将自纪元以来的秒数转换为带时区的时间戳。
示例 to_timestamp(1284352323.5)
结果 2010-09-13 04:32:03.5+00

transaction_timestamp()

描述 当前日期和时间(当前事务开始时)。
示例 transaction_timestamp()
结果 2022-10-08 12:44:46.122-07

带时区的时间戳字符串

在未加载时区扩展的情况下,TIMESTAMPTZ值将使用偏移量表示法进行字符串转换。这将允许您在无法访问时区信息的情况下正确指定一个瞬间。为了可移植性,TIMESTAMPTZ值将始终使用 GMT 偏移量显示

SELECT '2022-10-08 13:13:34-07'::TIMESTAMPTZ;
2022-10-08 20:13:34+00

如果加载了诸如 ICU 等时区扩展,则可以从字符串中解析时区并将其转换为本地时区中的表示形式

SELECT '2022-10-08 13:13:34 Europe/Amsterdam'::TIMESTAMPTZ::VARCHAR;
2022-10-08 04:13:34-07 -- the offset will differ based on your local time zone

ICU 带时区的时间戳运算符

下表显示了 ICU 扩展提供的适用于TIMESTAMP WITH TIME ZONE值的可用数学运算符。

运算符 描述 示例 结果
+ 添加 INTERVAL TIMESTAMPTZ '1992-03-22 01:02:03' + INTERVAL 5 DAY 1992-03-27 01:02:03
- TIMESTAMPTZ的减法 TIMESTAMPTZ '1992-03-27' - TIMESTAMPTZ '1992-03-22' 5 days
- 减去 INTERVAL TIMESTAMPTZ '1992-03-27 01:02:03' - INTERVAL 5 DAY 1992-03-22 01:02:03

无限值进行加减运算会产生相同的无限值。

ICU 带时区的时间戳函数

下表显示了 ICU 提供的适用于TIMESTAMP WITH TIME ZONE值的标量函数。

名称 描述
age(timestamptz, timestamptz) 减去参数,结果为两个时间戳之间的时间差。
age(timestamptz) 从 current_date 减去。
date_diff(part, startdate, enddate) 时间戳之间分区边界的数量。
date_part([part, ...], timestamptz) 将列出的子字段作为struct获取。列表必须是常量。
date_part(part, timestamptz) 获取子字段(等同于 extract)。
date_sub(part, startdate, enddate) 时间戳之间完整分区的数量。
date_trunc(part, timestamptz) 截断到指定的精度
datediff(part, startdate, enddate) date_diff 的别名。时间戳之间分区边界的数量。
datepart([part, ...], timestamptz) date_part 的别名。将列出的子字段作为struct获取。列表必须是常量。
datepart(part, timestamptz) date_part 的别名。获取子字段(等同于 extract)。
datesub(part, startdate, enddate) date_sub 的别名。时间戳之间完整分区的数量。
datetrunc(part, timestamptz) date_trunc 的别名。截断到指定的精度
epoch_ms(timestamptz) 将 timestamptz 转换为自纪元以来的毫秒数。
epoch_ns(timestamptz) 将 timestamptz 转换为自纪元以来的纳秒数。
epoch_us(timestamptz) 将 timestamptz 转换为自纪元以来的微秒数。
extract(field FROM timestamptz) TIMESTAMP WITH TIME ZONE中获取子字段
last_day(timestamptz) 该月的最后一天。
make_timestamptz(bigint, bigint, bigint, bigint, bigint, double, string) 给定部分和时区的TIMESTAMP WITH TIME ZONE
make_timestamptz(bigint, bigint, bigint, bigint, bigint, double) 当前时区中给定部分的TIMESTAMP WITH TIME ZONE
make_timestamptz(microseconds) 自纪元以来的给定微秒数的TIMESTAMP WITH TIME ZONE
strftime(timestamptz, format) 根据格式字符串TIMESTAMP WITH TIME ZONE值转换为字符串。
strptime(text, format) 如果指定了%Z,则根据格式字符串将字符串转换为TIMESTAMP WITH TIME ZONE
time_bucket(bucket_width, timestamptz[, offset]) timestamptz截断为宽度为bucket_width的网格。当bucket_width是月份或更粗粒度的单位时,网格锚定在2000-01-01 00:00:00+00:00[ + offset],否则锚定在2000-01-03 00:00:00+00:00[ + offset]。请注意,2000-01-03是星期一。
time_bucket(bucket_width, timestamptz[, origin]) timestamptz截断为宽度为bucket_width的网格。网格锚定在origin时间戳,当bucket_width是月份或更粗粒度的单位时,默认为2000-01-01 00:00:00+00:00,否则为2000-01-03 00:00:00+00:00。请注意,2000-01-03是星期一。
time_bucket(bucket_width, timestamptz[, timezone]) timestamptz截断为宽度为bucket_width的网格。网格锚定在origin时间戳,当bucket_width是月份或更粗粒度的单位时,默认为2000-01-01 00:00:00在提供的timezone中,否则为2000-01-03 00:00:00在提供的timezone中。默认时区是'UTC'。请注意,2000-01-03是星期一。

age(timestamptz, timestamptz)

描述 减去参数,结果为两个时间戳之间的时间差。
示例 age(TIMESTAMPTZ '2001-04-10', TIMESTAMPTZ '1992-09-20')
结果 8 years 6 months 20 days

age(timestamptz)

描述 从 current_date 减去。
示例 age(TIMESTAMP '1992-09-20')
结果 29 years 1 month 27 days 12:39:00.844

date_diff(part, startdate, enddate)

描述 时间戳之间分区边界的数量。
示例 date_diff('hour', TIMESTAMPTZ '1992-09-30 23:59:59', TIMESTAMPTZ '1992-10-01 01:58:00')
结果 2

date_part([part, ...], timestamptz)

描述 将列出的子字段作为struct获取。列表必须是常量。
示例 date_part(['year', 'month', 'day'], TIMESTAMPTZ '1992-09-20 20:38:40-07')
结果 {year: 1992, month: 9, day: 20}

date_part(part, timestamptz)

描述 获取子字段(等同于 extract)。
示例 date_part('minute', TIMESTAMPTZ '1992-09-20 20:38:40')
结果 38

date_sub(part, startdate, enddate)

描述 时间戳之间完整分区的数量。
示例 date_sub('hour', TIMESTAMPTZ '1992-09-30 23:59:59', TIMESTAMPTZ '1992-10-01 01:58:00')
结果 1

date_trunc(part, timestamptz)

描述 截断到指定的精度
示例 date_trunc('hour', TIMESTAMPTZ '1992-09-20 20:38:40')
结果 1992-09-20 20:00:00

datediff(part, startdate, enddate)

描述 date_diff 的别名。时间戳之间分区边界的数量。
示例 datediff('hour', TIMESTAMPTZ '1992-09-30 23:59:59', TIMESTAMPTZ '1992-10-01 01:58:00')
结果 2

datepart([part, ...], timestamptz)

描述 date_part 的别名。将列出的子字段作为struct获取。列表必须是常量。
示例 datepart(['year', 'month', 'day'], TIMESTAMPTZ '1992-09-20 20:38:40-07')
结果 {year: 1992, month: 9, day: 20}

datepart(part, timestamptz)

描述 date_part 的别名。获取子字段(等同于 extract)。
示例 datepart('minute', TIMESTAMPTZ '1992-09-20 20:38:40')
结果 38

datesub(part, startdate, enddate)

描述 date_sub 的别名。时间戳之间完整分区的数量。
示例 datesub('hour', TIMESTAMPTZ '1992-09-30 23:59:59', TIMESTAMPTZ '1992-10-01 01:58:00')
结果 1

datetrunc(part, timestamptz)

描述 date_trunc 的别名。截断到指定的精度
示例 datetrunc('hour', TIMESTAMPTZ '1992-09-20 20:38:40')
结果 1992-09-20 20:00:00

epoch_ms(timestamptz)

描述 将 timestamptz 转换为自纪元以来的毫秒数。
示例 epoch_ms('2022-11-07 08:43:04.123456+00'::TIMESTAMPTZ);
结果 1667810584123

epoch_ns(timestamptz)

描述 将 timestamptz 转换为自纪元以来的纳秒数。
示例 epoch_ns('2022-11-07 08:43:04.123456+00'::TIMESTAMPTZ);
结果 1667810584123456000

epoch_us(timestamptz)

描述 将 timestamptz 转换为自纪元以来的微秒数。
示例 epoch_us('2022-11-07 08:43:04.123456+00'::TIMESTAMPTZ);
结果 1667810584123456

extract(field FROM timestamptz)

描述 TIMESTAMP WITH TIME ZONE中获取子字段
示例 extract('hour' FROM TIMESTAMPTZ '1992-09-20 20:38:48')
结果 20

last_day(timestamptz)

描述 该月的最后一天。
示例 last_day(TIMESTAMPTZ '1992-03-22 01:02:03.1234')
结果 1992-03-31

make_timestamptz(bigint, bigint, bigint, bigint, bigint, double, string)

描述 给定部分和时区的TIMESTAMP WITH TIME ZONE
示例 make_timestamptz(1992, 9, 20, 15, 34, 27.123456, 'CET')
结果 1992-09-20 06:34:27.123456-07

make_timestamptz(bigint, bigint, bigint, bigint, bigint, double)

描述 当前时区中给定部分的TIMESTAMP WITH TIME ZONE
示例 make_timestamptz(1992, 9, 20, 13, 34, 27.123456)
结果 1992-09-20 13:34:27.123456-07

make_timestamptz(microseconds)

描述 自纪元以来的给定微秒数的TIMESTAMP WITH TIME ZONE
示例 make_timestamptz(1667810584123456)
结果 2022-11-07 16:43:04.123456-08

strftime(timestamptz, format)

描述 根据格式字符串TIMESTAMP WITH TIME ZONE值转换为字符串。
示例 strftime(timestamptz '1992-01-01 20:38:40', '%a, %-d %B %Y - %I:%M:%S %p')
结果 Wed, 1 January 1992 - 08:38:40 PM

strptime(text, format)

描述 如果指定了%Z,则根据格式字符串将字符串转换为TIMESTAMP WITH TIME ZONE
示例 strptime('Wed, 1 January 1992 - 08:38:40 PST', '%a, %-d %B %Y - %H:%M:%S %Z')
结果 1992-01-01 08:38:40-08

time_bucket(bucket_width, timestamptz[, offset])

描述 timestamptz截断为宽度为bucket_width的网格。当bucket_width是月份或更粗粒度的单位时,网格锚定在2000-01-01 00:00:00+00:00[ + offset],否则锚定在2000-01-03 00:00:00+00:00[ + offset]。请注意,2000-01-03是星期一。
示例 time_bucket(INTERVAL '10 minutes', TIMESTAMPTZ '1992-04-20 15:26:00-07', INTERVAL '5 minutes')
结果 1992-04-20 15:25:00-07

time_bucket(bucket_width, timestamptz[, origin])

描述 timestamptz截断为宽度为bucket_width的网格。网格锚定在origin时间戳,当bucket_width是月份或更粗粒度的单位时,默认为2000-01-01 00:00:00+00:00,否则为2000-01-03 00:00:00+00:00。请注意,2000-01-03是星期一。
示例 time_bucket(INTERVAL '2 weeks', TIMESTAMPTZ '1992-04-20 15:26:00-07', TIMESTAMPTZ '1992-04-01 00:00:00-07')
结果 1992-04-15 00:00:00-07

time_bucket(bucket_width, timestamptz[, timezone])

描述 timestamptz截断为宽度为bucket_width的网格。网格锚定在origin时间戳,当bucket_width是月份或更粗粒度的单位时,默认为2000-01-01 00:00:00在提供的timezone中,否则为2000-01-03 00:00:00在提供的timezone中。默认时区是'UTC'。请注意,2000-01-03是星期一。
示例 time_bucket(INTERVAL '2 days', TIMESTAMPTZ '1992-04-20 15:26:00-07', 'Europe/Berlin')
结果 1992-04-19 15:00:00-07 (=1992-04-20 00:00:00 Europe/Berlin)

还有专门的提取函数来获取子字段

ICU 时间戳表函数

下表显示了适用于TIMESTAMP WITH TIME ZONE类型的可用表函数。

名称 描述
generate_series(timestamptz, timestamptz, interval) 生成一个时间戳表,范围为闭区间(包括起始和结束时间戳),按指定间隔递增。
range(timestamptz, timestamptz, interval) 生成一个时间戳表,范围为半开区间(包括起始时间戳,但在结束时间戳之前停止),按指定间隔递增。

表函数边界不允许使用无限值。

generate_series(timestamptz, timestamptz, interval)

描述 生成一个时间戳表,范围为闭区间(包括起始和结束时间戳),按指定间隔递增。
示例 generate_series(TIMESTAMPTZ '2001-04-10', TIMESTAMPTZ '2001-04-11', INTERVAL 30 MINUTE)

range(timestamptz, timestamptz, interval)

描述 生成一个时间戳表,范围为半开区间(包括起始时间戳,但在结束时间戳之前停止),按指定间隔递增。
示例 range(TIMESTAMPTZ '2001-04-10', TIMESTAMPTZ '2001-04-11', INTERVAL 30 MINUTE)

ICU 不带时区的时间戳函数

下表显示了 ICU 提供的对纯TIMESTAMP值进行操作的标量函数。这些函数假设TIMESTAMP是一个“本地时间戳”。

本地时间戳实际上是一种将时区中的部分值编码为单个值的方式。它们应谨慎使用,因为由于夏令时,生成的值可能包含间隙和歧义。通常,相同的功能可以使用date_part函数的struct变体更可靠地实现。

名称 描述
current_localtime() 返回一个TIME,其 GMT 分箱值对应于当前时区的本地时间。
current_localtimestamp() 返回一个TIMESTAMP,其 GMT 分箱值对应于当前时区的本地日期和时间。
localtime current_localtime()函数调用的同义词。
localtimestamp current_localtimestamp()函数调用的同义词。
timezone(text, timestamp) 使用 GMT 中时间戳的日期部分,在给定时间区构造一个时间戳。实际上,参数是一个“本地”时间。
timezone(text, timestamptz) 使用给定时间区中时间戳的日期部分,构造一个时间戳。实际上,结果是一个“本地”时间。

current_localtime()

描述 返回一个TIME,其 GMT 分箱值对应于当前时区的本地时间。
示例 current_localtime()
结果 08:47:56.497

current_localtimestamp()

描述 返回一个TIMESTAMP,其 GMT 分箱值对应于当前时区的本地日期和时间。
示例 current_localtimestamp()
结果 2022-12-17 08:47:56.497

localtime

描述 current_localtime()函数调用的同义词。
示例 localtime
结果 08:47:56.497

localtimestamp

描述 current_localtimestamp()函数调用的同义词。
示例 localtimestamp
结果 2022-12-17 08:47:56.497

timezone(text, timestamp)

描述 使用 GMT 中时间戳的日期部分,在给定时间区构造一个时间戳。实际上,参数是一个“本地”时间。
示例 timezone('America/Denver', TIMESTAMP '2001-02-16 20:38:40')
结果 2001-02-16 19:38:40-08

timezone(text, timestamptz)

描述 使用给定时间区中时间戳的日期部分,构造一个时间戳。实际上,结果是一个“本地”时间。
示例 timezone('America/Denver', TIMESTAMPTZ '2001-02-16 20:38:40-05')
结果 2001-02-16 18:38:40

At Time Zone

AT TIME ZONE 语法是上述(两个参数的)timezone 函数的语法糖

SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'America/Denver' AS ts;
2001-02-16 19:38:40-08
SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'America/Denver' AS ts;
2001-02-16 18:38:40

请注意,不允许使用数字时区。

SELECT TIMESTAMP '2001-02-16 20:38:40-05' AT TIME ZONE '0200' AS ts;
Not implemented Error: Unknown TimeZone '0200'

无限值

应用于无限日期的函数将根据“是否有意义”返回相同的无限日期(例如greatest)或NULL(例如date_part)。一般来说,如果函数需要检查无限时间值的部分,结果将是NULL

日历

ICU 扩展还支持非格里高利历。如果当前是此类日历,则显示和分箱操作将使用该日历。