Documentation
/ SQL
/ Functions
Timestamp with Time Zone Functions
本节介绍用于检查和操作TIMESTAMP WITH TIME ZONE
(或TIMESTAMPTZ
)值的函数和运算符。
另请参阅相关的TIMESTAMP
函数。
尽管名称如此,这些值并不存储时区——只是一个像TIMESTAMP
一样的瞬间。
相反,它们要求使用当前时区对瞬间进行分箱和格式化,更多信息请参见关于DuckDB时区支持的博客文章。
时区支持由内置的ICU扩展提供。
在下面的示例中,假定当前时区为America/Los_Angeles
,并使用公历。
下表显示了可用于TIMESTAMPTZ
值的标量函数。
由于这些函数不涉及分箱或显示,
它们始终可用。
描述 |
当前日期和时间(当前事务的开始时间)。 |
示例 |
current_timestamp |
结果 |
2022-10-08 12:44:46.122-07 |
描述 |
当前日期和时间(当前事务的开始时间)。 |
示例 |
get_current_timestamp() |
结果 |
2022-10-08 12:44:46.122-07 |
Description |
The later of two timestamps. |
示例 |
greatest(TIMESTAMPTZ '1992-09-20 20:38:48', TIMESTAMPTZ '1992-03-22 01:02:03.1234') |
结果 |
1992-09-20 20:38:48-07 |
描述 |
如果带有时区的时间戳是有限的,则返回true,否则返回false。 |
示例 |
isfinite(TIMESTAMPTZ '1992-03-07') |
Result |
true |
描述 |
如果带有时区的时间戳是无限的,则返回true,否则返回false。 |
示例 |
isinf(TIMESTAMPTZ '-infinity') |
Result |
true |
Description |
The earlier of two timestamps. |
示例 |
least(TIMESTAMPTZ '1992-09-20 20:38:48', TIMESTAMPTZ '1992-03-22 01:02:03.1234') |
结果 |
1992-03-22 01:02:03.1234-08 |
Description |
Current date and time (start of current transaction). |
示例 |
now() |
结果 |
2022-10-08 12:44:46.122-07 |
描述 |
将自纪元以来的秒数转换为带有时区的时间戳。 |
示例 |
to_timestamp(1284352323.5) |
结果 |
2010-09-13 04:32:03.5+00 |
Description |
Current date and time (start of current transaction). |
示例 |
transaction_timestamp() |
Result |
2022-10-08 12:44:46.122-07 |
在没有加载时区扩展的情况下,TIMESTAMPTZ
值将使用偏移符号与字符串进行转换。
这将使您在没有访问时区信息的情况下正确指定一个时刻。
为了可移植性,TIMESTAMPTZ
值将始终使用 GMT 偏移量显示:
SELECT '2022-10-08 13:13:34-07'::TIMESTAMPTZ;
如果加载了诸如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扩展提供的TIMESTAMP WITH TIME ZONE
值可用的数学运算符。
Operator |
Description |
Example |
Result |
+ |
添加一个INTERVAL |
TIMESTAMPTZ '1992-03-22 01:02:03' + INTERVAL 5 DAY |
1992-03-27 01:02:03 |
- |
减去 TIMESTAMPTZ s |
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 |
Adding to or subtracting from infinite values produces the same infinite value.
下表显示了ICU为TIMESTAMP WITH TIME ZONE
值提供的标量函数。
Name |
Description |
age(timestamptz, timestamptz) |
减去参数,得到两个时间戳之间的时间差。 |
age(timestamptz) |
从当前日期减去。 |
date_diff(part, startdate, enddate) |
The number of partition boundaries between the timestamps. |
date_part([part, ...], timestamptz) |
获取列出的子字段作为struct 。列表必须是常量。 |
date_part(part, timestamptz) |
获取 子字段(等同于 extract)。 |
date_sub(part, startdate, enddate) |
The number of complete partitions between the timestamps. |
date_trunc(part, timestamptz) |
截断到指定的精度。 |
datediff(part, startdate, enddate) |
Alias of date_diff. The number of partition boundaries between the timestamps. |
datepart([part, ...], timestamptz) |
date_part 的别名。获取列出的 子字段 作为 struct 。列表必须是常量。 |
datepart(part, timestamptz) |
date_part 的别名。获取 子字段(等同于 extract)。 |
datesub(part, startdate, enddate) |
Alias of date_sub. The number of complete partitions between the timestamps. |
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) |
根据格式字符串将字符串转换为TIMESTAMP WITH TIME ZONE ,如果指定了%Z 。 |
time_bucket(bucket_width, timestamptz[, offset]) |
将 timestamptz 截断为指定的间隔 bucket_width 。桶通过 offset 间隔进行偏移。 |
time_bucket(bucket_width, timestamptz[, origin]) |
将 timestamptz 截断为指定的间隔 bucket_width 。桶相对于 origin timestamptz 对齐。origin 默认为 2000-01-03 00:00:00+00,用于不包含月或年间隔的桶,而对于月和年桶,则默认为 2000-01-01 00:00:00+00。 |
time_bucket(bucket_width, timestamptz[, timezone]) |
将 timestamptz 截断为指定的间隔 bucket_width 。桶的开始和结束时间使用 timezone 计算。timezone 是一个 varchar 类型,默认为 UTC。 |
Description |
Subtract arguments, resulting in the time difference between the two timestamps. |
示例 |
age(TIMESTAMPTZ '2001-04-10', TIMESTAMPTZ '1992-09-20') |
Result |
8 years 6 months 20 days |
Description |
Subtract from current_date. |
Example |
age(TIMESTAMP '1992-09-20') |
Result |
29 years 1 month 27 days 12:39:00.844 |
Description |
The number of partition boundaries between the timestamps. |
示例 |
date_diff('hour', TIMESTAMPTZ '1992-09-30 23:59:59', TIMESTAMPTZ '1992-10-01 01:58:00') |
Result |
2 |
Description |
Get the listed subfields as a struct . The list must be constant. |
示例 |
date_part(['year', 'month', 'day'], TIMESTAMPTZ '1992-09-20 20:38:40-07') |
Result |
{year: 1992, month: 9, day: 20} |
Description |
Get subfield (equivalent to extract). |
示例 |
date_part('minute', TIMESTAMPTZ '1992-09-20 20:38:40') |
Result |
38 |
Description |
The number of complete partitions between the timestamps. |
示例 |
date_sub('hour', TIMESTAMPTZ '1992-09-30 23:59:59', TIMESTAMPTZ '1992-10-01 01:58:00') |
Result |
1 |
Description |
Truncate to specified precision. |
示例 |
date_trunc('hour', TIMESTAMPTZ '1992-09-20 20:38:40') |
Result |
1992-09-20 20:00:00 |
Description |
Alias of date_diff. The number of partition boundaries between the timestamps. |
示例 |
datediff('hour', TIMESTAMPTZ '1992-09-30 23:59:59', TIMESTAMPTZ '1992-10-01 01:58:00') |
Result |
2 |
Description |
Alias of date_part. Get the listed subfields as a struct . The list must be constant. |
示例 |
datepart(['year', 'month', 'day'], TIMESTAMPTZ '1992-09-20 20:38:40-07') |
Result |
{year: 1992, month: 9, day: 20} |
Description |
Alias of date_part. Get subfield (equivalent to extract). |
示例 |
datepart('minute', TIMESTAMPTZ '1992-09-20 20:38:40') |
Result |
38 |
Description |
Alias of date_sub. The number of complete partitions between the timestamps. |
示例 |
datesub('hour', TIMESTAMPTZ '1992-09-30 23:59:59', TIMESTAMPTZ '1992-10-01 01:58:00') |
Result |
1 |
Description |
Alias of date_trunc. Truncate to specified precision. |
示例 |
datetrunc('hour', TIMESTAMPTZ '1992-09-20 20:38:40') |
Result |
1992-09-20 20:00:00 |
描述 |
将timestamptz转换为自纪元以来的毫秒数。 |
示例 |
epoch_ms('2022-11-07 08:43:04.123456+00'::TIMESTAMPTZ); |
Result |
1667810584123 |
描述 |
将时间戳转换为自纪元以来的纳秒数。 |
示例 |
epoch_ns('2022-11-07 08:43:04.123456+00'::TIMESTAMPTZ); |
结果 |
1667810584123456000 |
描述 |
将时间戳转换为自纪元以来的微秒数。 |
示例 |
epoch_us('2022-11-07 08:43:04.123456+00'::TIMESTAMPTZ); |
结果 |
1667810584123456 |
描述 |
从TIMESTAMP WITH TIME ZONE 获取子字段。 |
示例 |
extract('hour' FROM TIMESTAMPTZ '1992-09-20 20:38:48') |
Result |
20 |
Description |
The last day of the month. |
示例 |
last_day(TIMESTAMPTZ '1992-03-22 01:02:03.1234') |
Result |
1992-03-31 |
描述 |
给定部分和时区的TIMESTAMP WITH TIME ZONE 。 |
示例 |
make_timestamptz(1992, 9, 20, 15, 34, 27.123456, 'CET') |
结果 |
1992-09-20 06:34:27.123456-07 |
描述 |
当前时区中给定部分的TIMESTAMP WITH TIME ZONE 。 |
示例 |
make_timestamptz(1992, 9, 20, 13, 34, 27.123456) |
结果 |
1992-09-20 13:34:27.123456-07 |
描述 |
自纪元以来的给定微秒的TIMESTAMP WITH TIME ZONE 。 |
示例 |
make_timestamptz(1667810584123456) |
结果 |
2022-11-07 16:43:04.123456-08 |
描述 |
将TIMESTAMP WITH TIME ZONE 值根据格式字符串转换为字符串。 |
示例 |
strftime(timestamptz '1992-01-01 20:38:40', '%a, %-d %B %Y - %I:%M:%S %p') |
Result |
Wed, 1 January 1992 - 08:38:40 PM |
描述 |
根据格式字符串将字符串转换为TIMESTAMP WITH TIME ZONE ,如果指定了%Z 。 |
示例 |
strptime('Wed, 1 January 1992 - 08:38:40 PST', '%a, %-d %B %Y - %H:%M:%S %Z') |
结果 |
1992-01-01 08:38:40-08 |
描述 |
将timestamptz 截断为指定的间隔bucket_width 。桶通过offset 间隔进行偏移。 |
示例 |
time_bucket(INTERVAL '10 minutes', TIMESTAMPTZ '1992-04-20 15:26:00-07', INTERVAL '5 minutes') |
结果 |
1992-04-20 15:25:00-07 |
描述 |
通过指定的间隔bucket_width 截断timestamptz 。桶相对于origin timestamptz对齐。对于不包含月或年间隔的桶,origin 默认为2000-01-03 00:00:00+00,对于月和年桶,默认为2000-01-01 00:00:00+00。 |
示例 |
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 |
描述 |
通过指定的间隔 bucket_width 截断 timestamptz 。桶的开始和结束时间使用 timezone 计算。timezone 是一个 varchar 类型,默认为 UTC。 |
示例 |
time_bucket(INTERVAL '2 days', TIMESTAMPTZ '1992-04-20 15:26:00-07', 'Europe/Berlin') |
结果 |
1992-04-19 15:00:00-07 |
There are also dedicated extraction functions to get the subfields.
下表显示了适用于TIMESTAMP WITH TIME ZONE
类型的可用表函数。
不允许将无限值作为表函数边界。
描述 |
生成一个时间戳表,时间戳范围是闭区间(包括开始时间戳和结束时间戳),按间隔步进。 |
示例 |
generate_series(TIMESTAMPTZ '2001-04-10', TIMESTAMPTZ '2001-04-11', INTERVAL 30 MINUTE) |
描述 |
生成一个时间戳表,时间戳在半开范围内(包括起始时间戳,但在结束时间戳之前停止),按间隔步进。 |
示例 |
range(TIMESTAMPTZ '2001-04-10', TIMESTAMPTZ '2001-04-11', INTERVAL 30 MINUTE) |
下表显示了ICU提供的对普通TIMESTAMP
值进行操作的标量函数。
这些函数假设TIMESTAMP
是一个“本地时间戳”。
本地时间戳实际上是一种将时区的部分值编码为单个值的方式。
由于夏令时的原因,生成的值可能包含间隙和歧义,因此应谨慎使用。
通常,使用date_part
函数的struct
变体可以更可靠地实现相同的功能。
描述 |
返回一个TIME ,其GMT bin值对应于当前时区的本地时间。 |
示例 |
current_localtime() |
结果 |
08:47:56.497 |
描述 |
返回一个TIMESTAMP ,其GMT bin值对应于当前时区的本地日期和时间。 |
示例 |
current_localtimestamp() |
结果 |
2022-12-17 08:47:56.497 |
描述 |
current_localtime() 函数调用的同义词。 |
示例 |
localtime |
结果 |
08:47:56.497 |
描述 |
current_localtimestamp() 函数调用的同义词。 |
示例 |
localtimestamp |
结果 |
2022-12-17 08:47:56.497 |
描述 |
使用日期部分的GMT时间戳来构造给定时区的时间戳。实际上,参数是一个“本地”时间。 |
示例 |
timezone('America/Denver', TIMESTAMP '2001-02-16 20:38:40') |
结果 |
2001-02-16 19:38:40-08 |
描述 |
使用给定时区中的时间戳的日期部分来构建时间戳。实际上,结果是一个“本地”时间。 |
示例 |
timezone('America/Denver', TIMESTAMPTZ '2001-02-16 20:38:40-05') |
结果 |
2001-02-16 18:38:40 |
AT TIME ZONE
语法是上面列出的(两个参数的)timezone
函数的语法糖:
SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'America/Denver' AS ts;
SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'America/Denver' AS ts;
请注意,数字时区是不允许的:
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扩展还支持非公历日历。如果当前使用的是这种日历,那么显示和分箱操作将使用该日历。