ConvertTimezone
convertTimezone 将时间戳转换为指定时区,通过在时间戳上加或减正确的间隔来实现。
| 语法 | 示例 |
|---|---|
convertTimezone(column, target, source) |
convertTimezone("2022-12-28T12:00:00", "Canada/Pacific", "Canada/Eastern") |
| 将时间戳从源时区转换到目标时区。 | 返回值为 2022-12-28T09:00:00,显示为 2022年12月28日 09:00 |
时间戳和时区处理起来相当棘手(容易出错,而且很难发现错误),因此您应该只在数据的解释对基于时间的截止日期敏感时才尝试使用 convertTimezone。
例如,如果您正在跟踪用户随时间推移的登录情况,用户在周一而不是周二登录可能不会影响您的业务。但是,如果您使用 Metabase 来处理一些精确的事情,比如报税,您(和政府)会更关心 12 月 31 日和 1 月 1 日交易之间的区别。
支持的时区
Metabase 支持 tz 数据库时区。
参数
列 可以是以下任何一种
- 时间戳列的名称,
- 一个返回 时间戳 的自定义表达式,或者
- 一个格式为
"YYYY-MM-DD或"YYYY-MM-DDTHH:MM:SS"的字符串。
目标:
- 您要为列分配的时区的名称。
源:
- 您的列当前时区的名称。
- 对于数据类型为
无时区的时间戳的列或表达式是必需的。 - 对于数据类型为
带时区的时间戳的列或表达式是可选的。 - 有关更多信息,请参阅 接受的数据类型。
我们支持 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 |
如果 **源时间** 存储为 带时区的时间戳 或 带偏移的时间戳,您只需要提供 目标 时区
convertTimezone([Source Time], 'EST')
如果 **源时间** 存储为 无时区的时间戳,您必须提供 源 时区(这取决于您的数据库时区)
convertTimezone([Source Time], 'EST', 'UTC')
通常最好将 convertTimezone 列标记为目标时区的名称(或将目标时区添加到模型的元数据中)。我们保证这会让您在有人不可避免地质疑为什么数字不匹配时生活得更轻松。
如果结果不符合预期
选择源时区
进行时区转换时,请确保您了解正在处理的源时区。同一表、问题或模型中的不同列(甚至不同行)可以处于不同的“源”时区。
| 可能的源时区 | 描述 | 示例 |
|---|---|---|
| 客户端时区 | 事件发生所在地的时区。 | 一个网络分析服务可能会捕获每个访问您网站的人的本地时区数据。 |
| 数据库时区 | 已添加到数据库时间戳中的时区元数据。 | 将所有时间戳存储为 UTC 是一种常见的数据库实践。 |
| 无时区 | 缺少时区元数据 | 数据库不要求您存储带时区元数据的时间戳。 |
| Metabase 报告时区 | Metabase 用于显示时间戳的时区。 | Metabase 可以显示 PST 的日期和时间,即使这些日期和时间以 UTC 形式存储在您的数据库中。 |
例如,假设您有一个表,其中包含每个访问您网站的人的一行。仅从查看 2022年12月28日 12:00 PM 很难判断“原始”时间戳是
- 使用您数据库的时区(通常是 UTC)存储的,
- 未存储时区元数据(例如,如果网站访问者在 HKT,则时间戳
2022年12月28日 12:00 PM可能“隐含”使用香港时间), - 在您的 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 的输出始终是 无时区的时间戳。
限制
convertTimezone 目前对以下数据库不可用
- Amazon Athena
- Databricks
- Druid
- MongoDB
- Presto
- SparkSQL
- SQLite
- Metabase 示例数据库
关于源时区的注意事项
Metabase 显示没有时区或偏移信息的时间戳,这就是为什么在使用 convertTimezone 时必须非常注意 源时区。
Metabase 报告时区仅适用于 带时区的时间戳 或 带偏移的时间戳 数据类型。例如
| 数据库中的原始时间戳 | 数据类型 | 报告时区 | 显示为 |
|---|---|---|---|
2022-12-28T12:00:00 AT TIME ZONE 'CST' |
带时区的时间戳 |
‘Canada/Eastern’ | 12月28日,下午1:00 |
2022-12-28T12:00:00-06:00 |
带偏移量的时间戳 |
‘Canada/Eastern’ | 12月28日,下午1:00 |
2022-12-28T12:00:00 |
不带时区的时间戳 |
‘Canada/Eastern’ | 12月28日,午夜12:00 AM |
Metabase 报告时区将不适用于 convertTimezone 表达式的输出。例如
convertTimezone("2022-12-28T12:00:00 AT TIME ZONE 'Canada/Central'", "Canada/Pacific", "Canada/Central")
将生成一个原始的 无时区的时间戳
2022-12-28T04:00:00
并在 Metabase 中显示为
Dec 28, 2022, 4:00 AM
如果您在 无时区的时间戳 上使用 convertTimezone,请确保将 ‘UTC’ 用作 源 时区,否则表达式将错误地移动您的时间戳。例如,如果我们的 无时区的时间戳“隐含”为 CST,我们应该使用 ‘UTC’ 作为 源 参数以获得与上面相同的结果。
例如,如果我们选择 ‘CST’ 作为 无时区的时间戳 的 源 时区
convertTimezone("2022-12-28T12:00:00", "Canada/Pacific", "Canada/Central")
我们将获得原始的 无时区的时间戳
2022-12-28T10:00:00
在 Metabase 中显示为
Dec 28, 2022, 10:00 AM
相关函数
本节介绍与 Metabase convertTimezone 表达式工作方式相同的函数和公式,并附有关于如何为您的用例选择最佳选项的说明。
SQL
当您使用查询构建器运行查询时,Metabase 会将您的图形查询设置(过滤器、摘要等)转换为查询,并针对您的数据库运行该查询以获取结果。
如果我们的 时间戳示例数据 是 PostgreSQL 数据库中存储的 无时区的时间戳
SELECT source_time::TIMESTAMP AT TIME ZONE 'UTC' AT TIME ZONE 'EST' AS team_report_time_est
等同于 convertTimezone 表达式,并将 源 参数设置为 ‘UTC’
convertTimezone([Source Time], "Canada/Eastern", "UTC")
如果 source_time 是 带时区的时间戳 或 带偏移的时间戳(例如,在 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 对象(基本上将 无时区的时间戳 转换为 带时区的时间戳),然后使用 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 的文档。