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 zonetimestamp with offset,则只需提供 target 时区

convertTimezone([Source Time], 'EST')

如果源时间存储为 timestamp without time zone,您必须提供 source 时区(这将取决于您的数据库时区)

convertTimezone([Source Time], 'EST', 'UTC')

通常,最好使用目标时区的名称标记 convertTimezone 列(或将目标时区添加到模型的元数据中)。我们保证当有人不可避免地问为什么数字不匹配时,这将使您的生活更轻松。

如果您没有获得预期的结果

  • 检查您是否选择了正确的源时区
  • 咨询您的数据库管理员关于 timestamp with time zonetimestamp 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 zonetimestamp 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_timetimestamp with time zonetimestamp 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 版本的文档。