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 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 的区别(更多信息请参阅接受的数据类型)。

选择源时区

进行时区转换时,请确保您了解正在使用的源时区。同一表、问题或模型中的不同列(甚至不同行)可以处于不同的“源”时区。

可能的源时区 描述 示例
客户端时区 事件发生的时区。 网络分析服务可能会以每个访问您网站的人的当地时区捕获数据。
数据库时区 已添加到数据库时间戳中的时区元数据。 将所有时间戳存储为 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 zonetimestamp 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 zonesource 时区

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 版本的文档。

© . All rights reserved.