ConvertTimezone
convertTimezone
通过在时间戳中添加或减去正确的时间间隔,将时间戳转换为指定时区。
语法 | 示例 |
---|---|
convertTimezone(column, target, source) |
convertTimezone("2022-12-28T12:00:00", "Canada/Pacific", "Canada/Eastern") |
将时间戳从源时区转换到目标时区。 | 返回 2022-12-28T09:00:00 值,显示为 2022 年 12 月 28 日 9:00 AM |
时间戳和时区处理起来相当棘手(很容易出错,而且难以发现),因此只有当您的数据解释对基于时间的截止点敏感时,才应尝试使用 convertTimezone
。
例如,如果您正在跟踪用户随时间的登录情况,那么如果某些登录算在周一而不是周二,您的业务可能不会受到太大影响。但是,如果您使用 Metabase 进行精确操作,例如报税,那么您(和政府)可能会非常在意 12 月 31 日与 1 月 1 日之间交易的差异。
支持的时区
Metabase 支持 tz 数据库时区。
参数
column
可以是以下任意一种
- 时间戳列的名称,
- 一个返回时间戳的自定义表达式,或者
- 格式为
"YYYY-MM-DD
或"YYYY-MM-DDTHH:MM:SS"
的字符串。
target
:
- 您希望分配给列的时区名称。
source
:
- 列当前时区的名称。
- 对于数据类型为
timestamp without time zone
的列或表达式是必需的。 - 对于数据类型为
timestamp with time zone
的列或表达式是可选的。 - 更多信息请参阅接受的数据类型。
我们支持 tz 数据库时区名称(例如 “Canada/Eastern” 而不是 “EST”)。
创建自定义报告日期
假设您有一些时间序列数据,这些数据存储在一个或多个时区(**源时间**)。您想为居住在 EST 的团队创建自定义报告日期。
源时间 | 团队报告时间 (EST) |
---|---|
2022 年 12 月 28 日 10:00:00 | 2022 年 12 月 28 日 07:00:00 |
2022 年 12 月 28 日 21:00:00 | 2022 年 12 月 28 日 19:00:00 |
2022 年 12 月 27 日 08:00:00 | 2022 年 12 月 27 日 05:00:00 |
如果**源时间**存储为 timestamp with time zone
或 timestamp with offset
,您只需提供 target
时区
convertTimezone([Source Time], 'EST')
如果**源时间**存储为 timestamp without time zone
,则*必须*提供 source
时区(这将取决于您的数据库时区)
convertTimezone([Source Time], 'EST', 'UTC')
通常,最好用目标时区名称标记 convertTimezone
列(或将目标时区添加到模型的元数据中)。我们保证这会使您的工作更轻松,因为总会有人问为什么数字不匹配。
如果您没有得到预期结果
- 检查您是否选择了正确的源时区。
- 向您的数据库管理员咨询
timestamp with time zone
与timestamp without time zone
的区别(更多信息请参阅接受的数据类型)。
选择源时区
进行时区转换时,请确保您了解正在使用的源时区。同一表、问题或模型中的不同列(甚至不同行)可以处于不同的“源”时区。
可能的源时区 | 描述 | 示例 |
---|---|---|
客户端时区 | 事件发生的时区。 | 网络分析服务可能会以每个访问您网站的人的当地时区捕获数据。 |
数据库时区 | 已添加到数据库时间戳中的时区元数据。 | 将所有时间戳存储为 UTC 是常见的数据库实践。 |
无时区 | 缺少时区元数据 | 数据库不*要求*您存储带有时区元数据的时间戳。 |
Metabase 报告时区 | Metabase 用于*显示*时间戳的时区。 | Metabase 可以以 PST 格式显示日期和时间,即使这些日期和时间在您的数据库中存储为 UTC。 |
例如,假设您有一个表,其中每一行代表一个访问您网站的人。仅凭查看 2022 年 12 月 28 日 12:00 PM
,很难判断“原始”时间戳是
- 使用数据库的时区(通常是 UTC)存储的,
- 存储时没有时区元数据(例如,如果网站访问者位于 HKT,则时间戳
2022 年 12 月 28 日 12:00 PM
可能“隐式”使用香港时间), - 在您的 Metabase 报告时区中*显示*。
更多详细信息,请参阅限制。
接受的数据类型
数据类型 | 适用于 convertTimezone |
---|---|
字符串 | ❌ |
数字 | ❌ |
时间戳 | ✅ |
布尔值 | ❌ |
JSON | ❌ |
我们使用“时间戳”和“日期时间”来指代 Metabase 支持的任何时间数据类型。
如果您的时间戳在数据库中存储为字符串或数字,管理员可以从“表元数据”页面将其转换为时间戳。
要使用 convertTimezone
而不出现错误或难以察觉的问题,您应该知道 timestamp
数据类型有几种变体
数据类型 | 描述 | 示例 |
---|---|---|
带时区的时间戳 |
包含位置信息。 | 2022-12-28T12:00:00 AT TIME ZONE 'America/Toronto' |
带偏移量的时间戳 |
包含与 UTC 的时间差。 | 2022-12-28T12:00:00-04:00 |
无时区的时间戳 |
无时区信息。 | 2022-12-28T12:00:00 |
请注意,时间戳的第一部分是 UTC 时间(与 GMT 相同)。时区或偏移量告诉您特定时区需要添加或减去多少时间。
convertTimezone
将适用于所有三种类型的时间戳,但 convertTimezone
的输出始终是 timestamp without time zone
。
限制
convertTimezone
目前不适用于以下数据库
- Amazon Athena
- Databricks
- Druid
- MongoDB
- Presto
- SparkSQL
- SQLite
- Metabase 示例数据库
源时区说明
Metabase 显示不带时区或偏移信息的时间戳,这就是在使用 convertTimezone
时必须非常小心源时区的原因。
Metabase 报告时区仅适用于 timestamp with time zone
或 timestamp with offset
数据类型。例如
数据库中的原始时间戳 | 数据类型 | 报告时区 | 显示为 |
---|---|---|---|
2022-12-28T12:00:00 AT TIME ZONE 'CST' |
带时区的时间戳 |
‘Canada/Eastern’ | 2022 年 12 月 28 日 7:00 AM |
2022-12-28T12:00:00-06:00 |
带偏移量的时间戳 |
‘Canada/Eastern’ | 2022 年 12 月 28 日 7:00 AM |
2022-12-28T12:00:00 |
无时区的时间戳 |
‘Canada/Eastern’ | 2022 年 12 月 28 日 12:00 AM |
Metabase 报告时区不适用于 convertTimezone
表达式的输出。例如
convertTimezone("2022-12-28T12:00:00 AT TIME ZONE 'Canada/Central'", "Canada/Pacific", "Canada/Central")
将生成原始 timestamp without time zone
2022-12-28T04:00:00
并在 Metabase 中显示为
Dec 28, 2022, 4:00 AM
如果您在 timestamp without time zone
上使用 convertTimezone
,请确保使用“UTC”作为 source
时区,否则表达式将错误地偏移您的时间戳。例如,如果我们的 timestamp without time zone
只是“隐含”为 CST,我们应该使用“UTC”作为 source
参数以获得与上面相同的结果。
例如,如果我们将“CST”选作 timestamp without time zone
的 source
时区
convertTimezone("2022-12-28T12:00:00", "Canada/Pacific", "Canada/Central")
我们将获得原始的 timestamp without time zone
2022-12-28T10:00:00
并在 Metabase 中显示为
Dec 28, 2022, 10:00 AM
相关函数
本节涵盖了与 Metabase convertTimezone
表达式工作方式相同的函数和公式,并附有关于如何为您的用例选择最佳选项的说明。
SQL
当您使用查询构建器运行问题时,Metabase 会将您的图形查询设置(筛选器、汇总等)转换为查询,并针对您的数据库运行该查询以获取结果。
如果我们的时间戳示例数据是存储在 PostgreSQL 数据库中的 timestamp without time zone
SELECT source_time::TIMESTAMP AT TIME ZONE 'UTC' AT TIME ZONE 'EST' AS team_report_time_est
与 convertTimezone
表达式相同,source
参数设置为“UTC”
convertTimezone([Source Time], "Canada/Eastern", "UTC")
如果 source_time
是 timestamp with time zone
或 timestamp with offset
(例如,在 Snowflake 数据库中),那么我们不需要在 SQL 或 Metabase 中指定源时区。
SELECT convert_timezone('America/Toronto', source_time) AS team_report_time_est
与
convertTimezone([Source Time], "Canada/Eastern")
请记住,时区名称取决于您的数据库。例如,Snowflake 不接受大多数时区缩写(如 EST)。
电子表格
如果我们的时间戳示例数据在电子表格中,“源时间”位于 A 列,我们可以通过显式减去小时将其更改为 EST
A1 - TIME(5, 0, 0)
以获得与
convertTimezone([Client Time], "Canada/Eastern")
Python
如果时间戳示例数据存储在 pandas
数据框中,您可以首先将**源时间**列转换为带时区的 timestamp
对象(基本上是将 timestamp without time zone
转换为 timestamp with time zone
),然后使用 tz_convert
将时区更改为 EST
df['Source Time (UTC)'] = pd.to_timestamp(df['Source Time'], utc=True)
df['Team Report Time (EST)'] = df['Source Time (UTC)'].dt.tz_convert(tz='Canada/Eastern')
以执行与嵌套 convertTimezone
表达式相同的操作
convertTimezone(convertTimezone([Source Time], "UTC"), "Canada/Eastern", "UTC")
延伸阅读
阅读其他 Metabase 版本的文档。