- 安装
- 文档
- 入门
- 连接
- 数据导入
- 客户端 API
- 概览
- ADBC
- C
- C++
- CLI
- Dart
- Go
- Java (JDBC)
- Julia
- Node.js (已弃用)
- Node.js (Neo)
- ODBC
- PHP
- Python
- R
- Rust
- Swift
- Wasm
- SQL
- 介绍
- 语句
- 概览
- ANALYZE
- ALTER TABLE
- ALTER VIEW
- ATTACH 和 DETACH
- CALL
- CHECKPOINT
- COMMENT ON
- COPY
- CREATE INDEX
- CREATE MACRO
- CREATE SCHEMA
- CREATE SECRET
- CREATE SEQUENCE
- CREATE TABLE
- CREATE VIEW
- CREATE TYPE
- DELETE
- DESCRIBE
- DROP
- EXPORT 和 IMPORT DATABASE
- INSERT
- LOAD / INSTALL
- PIVOT
- 性能分析
- SELECT
- SET / RESET
- SET VARIABLE
- SUMMARIZE
- 事务管理
- UNPIVOT
- UPDATE
- USE
- VACUUM
- 查询语法
- SELECT
- FROM 和 JOIN
- WHERE
- GROUP BY
- GROUPING SETS
- HAVING
- ORDER BY
- LIMIT 和 OFFSET
- SAMPLE
- 展开嵌套
- WITH
- WINDOW
- QUALIFY
- VALUES
- FILTER
- 集合操作
- 预处理语句
- 数据类型
- 表达式
- 函数
- 概览
- 聚合函数
- 数组函数
- 位字符串函数
- Blob 函数
- 日期格式化函数
- 日期函数
- 日期部分函数
- 枚举函数
- 间隔函数
- Lambda 函数
- 列表函数
- 映射函数
- 嵌套函数
- 数值函数
- 模式匹配
- 正则表达式
- 结构体函数
- 文本函数
- 时间函数
- 时间戳函数
- 带时区时间戳函数
- 联合函数
- 实用函数
- 窗口函数
- 约束
- 索引
- 元查询
- DuckDB 的 SQL 方言
- 示例
- 配置
- 扩展
- 核心扩展
- 概览
- 自动补全
- Avro
- AWS
- Azure
- Delta
- DuckLake
- 编码
- Excel
- 全文搜索
- httpfs (HTTP 和 S3)
- Iceberg
- ICU
- inet
- jemalloc
- MySQL
- PostgreSQL
- 空间
- SQLite
- TPC-DS
- TPC-H
- UI
- VSS
- 指南
- 概览
- 数据查看器
- 数据库集成
- 文件格式
- 概览
- CSV 导入
- CSV 导出
- 直接读取文件
- Excel 导入
- Excel 导出
- JSON 导入
- JSON 导出
- Parquet 导入
- Parquet 导出
- 查询 Parquet 文件
- 使用 file: 协议访问文件
- 网络和云存储
- 概览
- HTTP Parquet 导入
- S3 Parquet 导入
- S3 Parquet 导出
- S3 Iceberg 导入
- S3 Express One
- GCS 导入
- Cloudflare R2 导入
- 通过 HTTPS / S3 使用 DuckDB
- Fastly 对象存储导入
- 元查询
- ODBC
- 性能
- Python
- 安装
- 执行 SQL
- Jupyter Notebooks
- marimo Notebooks
- Pandas 上的 SQL
- 从 Pandas 导入
- 导出到 Pandas
- 从 Numpy 导入
- 导出到 Numpy
- Arrow 上的 SQL
- 从 Arrow 导入
- 导出到 Arrow
- Pandas 上的关系型 API
- 多个 Python 线程
- 与 Ibis 集成
- 与 Polars 集成
- 使用 fsspec 文件系统
- SQL 编辑器
- SQL 功能
- 代码片段
- 故障排除
- 术语表
- 离线浏览
- 操作手册
- 开发
- 内部结构
- 为什么选择 DuckDB
- 行为准则
- 发布日历
- 路线图
- 站点地图
- 在线演示
本节介绍用于检查和操作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 扩展还支持非格里高利历。如果当前是此类日历,则显示和分箱操作将使用该日历。