ConvertTimezone
convertTimezone
通过从时间戳添加或减去正确的间隔,将时间戳移至指定的时区。
语法 | 示例 |
---|---|
convertTimezone(列, 目标, 源) |
convertTimezone("2022-12-28T12:00:00", "Canada/Pacific", "Canada/Eastern") |
将时间戳从源时区移至目标时区。 | 返回值 2022-12-28T09:00:00 ,显示为 2022 年 12 月 28 日上午 9:00 |
时间戳和时区相当棘手(很容易犯错,而且很难发现错误),因此,如果数据的解释对基于时间的截止时间很敏感,您才应该尝试使用 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
的区别(有关更多信息,请参阅接受的数据类型)。
选择源时区
在进行时区转换时,请确保您知道正在使用的源时区。同一表、问题或模型中的不同列(甚至不同的行)可能位于不同的“源”时区。
可能的源时区 | 描述 | 示例 |
---|---|---|
客户端时区 | 事件发生的时区。 | Web 分析服务可能会捕获访问您网站的每个人的当地时区的数据。 |
数据库时区 | 已添加到数据库中时间戳的时区元数据。 | 将所有时间戳存储为 UTC 是一种常见的数据库做法。 |
无时区 | 缺少时区元数据 | 数据库不要求您存储带有时区元数据的时间戳。 |
Metabase 报告时区 | Metabase 用于显示时间戳的时区。 | 即使日期和时间在数据库中存储为 UTC,Metabase 也可以使用 PST 显示日期和时间。 |
例如,假设您有一个表,其中每行对应一个访问您网站的人。仅从查看 2022 年 12 月 28 日下午 12:00
很难判断“原始”时间戳是
- 使用数据库的时区(通常为 UTC)存储,
- 不带时区元数据存储(例如,如果网站访问者位于 HKT,则时间戳
2022 年 12 月 28 日下午 12:00
可能“隐式”使用香港时间), - 显示在您的 Metabase 报告时区中。
有关更多详细信息,请参阅限制。
接受的数据类型
数据类型 | 适用于 convertTimezone |
---|---|
字符串 | ❌ |
数字 | ❌ |
时间戳 | ✅ |
布尔值 | ❌ |
JSON | ❌ |
我们使用“timestamp”和“datetime”来谈论 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 |
2022-12-28T12:00:00-06:00 |
带偏移量的时间戳 |
‘Canada/Eastern’ | 2022 年 12 月 28 日,上午 7:00 |
2022-12-28T12:00:00 |
不带时区的时间戳 |
‘Canada/Eastern’ | 2022 年 12 月 28 日,凌晨 12:00 |
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
参数以获得与上述相同的结果。
例如,如果我们为 timestamp without time zone
选择“CST”作为 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 版本的文档。