28

我将数据存储在 google big query 的 unixtimestamp 中。但是,当用户要求报告时,她需要按当地时区过滤和分组数据。

数据存储在格林威治标准时间。用户可能希望查看 EST 中的数据。报告可能会要求按日期对数据进行分组。

我在这里看不到时区转换功能:

有谁知道我如何在 bigquery 中做到这一点?即在将时间戳转换为不同的时区后如何分组?

4

7 回答 7

39

BigQuery 中的标准 SQL 具有内置函数

DATE(timestamp_expression, timezone)
TIME(timestamp, timezone)
DATETIME(timestamp_expression, timezone)

例子:

SELECT 
   original,
   DATETIME(original, "America/Los_Angeles") as adjusted
FROM sometable;

+---------------------+---------------------+
| original            | adjusted            |
+---------------------+---------------------+
| 2008-12-25 05:30:00 | 2008-12-24 21:30:00 |
+---------------------+---------------------+

您可以使用标准IANA 时区名称或偏移量

于 2017-04-11T14:45:08.223 回答
29

截至 2016 年 9 月,BigQuery 已采用标准 SQL,您现在只需使用“DATE(timestamp, timezone)”函数来偏移时区。你可以在这里参考他们的文档:

BigQuery 日期文档

于 2016-10-19T19:51:54.960 回答
5

对于那些在这里绊倒的人:

如何将时间戳转换为另一个时区?

鉴于 TIMESTAMP 值一旦构造,就存储为 UTC,并且 TIMESTAMP 没有构造函数 (TIMESTAMP, STRING),您可以将时间戳转换为另一个时区,方法是先将其转换为 DATETIME,然后从新时区的 DATETIME:

SELECT TIMESTAMP(DATETIME(timestamp_field, '{timezone}'))

例子:

SELECT
    input_tz,
    input,
    'America/Montreal' AS output_tz,
    TIMESTAMP(DATETIME(input,'America/Montreal')) AS output
FROM (
    SELECT 'US/Pacific' AS input_tz, TIMESTAMP(DATETIME(DATE(2021, 1, 1), TIME(16, 0, 0)), 'US/Pacific') AS input
    UNION ALL
    SELECT 'UTC' AS input_tz, TIMESTAMP(DATETIME(DATE(2021, 1, 1), TIME(16, 0, 0)), 'UTC') AS input
    UNION ALL
    SELECT 'Europe/Berlin' AS input_tz, TIMESTAMP(DATETIME(DATE(2021, 1, 1), TIME(16, 0, 0)), 'Europe/Berlin') AS input
) t

结果是:

input_tz 输入 output_tz 输出
1 美国/太平洋 2021-01-02 00:00:00 UTC 美国/蒙特利尔 2021-01-01 19:00:00 UTC
2 世界标准时间 2021-01-01 16:00:00 UTC 美国/蒙特利尔 2021-01-01 11:00:00 UTC
3 欧洲/柏林 2021-01-01 15:00:00 UTC 美国/蒙特利尔 2021-01-0110:00:00 UTC

如何从 DATETIME 值中去除时区信息?

BigQuery 中的 DATETIME 是天真的时区,因此它们不包含时区信息。话虽这么说,如果您拥有可以知道 DATETIME 的时区的业务知识,则可以通过将其转换为具有已知时区的 TIMESTAMP 来去除该时区偏移:

SELECT TIMESTAMP(datetime_value, '{timezone}')

鉴于 TIMESTAMP 以 UTC 存储值,如果这是您首选的存储方法,您可以重新转换为 DATETIME,但现在您会知道您的 DATETIME 是 UTC :)

希望这会有所帮助!:)

于 2021-07-01T20:42:10.673 回答
4

你的前提是对的。如果你这样分组,那么想要 EST 或 EDT 的用户将得到不正确的日期分组:

GROUP BY UTC_USEC_TO_DAY(ts_field)

但是只要你计算出你的用户想要的偏移量,你仍然可以在服务器上进行完整的计算。例如,如果 EST 比 UTC 晚 5 小时,则查询如下:

GROUP BY UTC_USEC_TO_DAY(ts_field - (5*60*60*1000*1000000) )

只需将“5”参数化为以小时为单位的偏移量,就可以了。以下是基于其中一个示例数据集的示例:

SELECT
  COUNT(*) as the_count,
  UTC_USEC_TO_DAY(timestamp * 1000000 - (5*60*60*1000*1000000) ) as the_day
FROM
  [publicdata:samples.wikipedia]
WHERE
  comment CONTAINS 'disaster'
  and timestamp >= 1104537600
GROUP BY
  the_day
ORDER BY
  the_day

您可以删除偏移量以查看某些编辑如何移动到不同的日期。

于 2012-09-19T18:32:37.403 回答
3

2016 年更新请看下面的答案,BigQuery 现在提供时间戳和时区方法


您是对的 - BigQuery 不提供任何时间戳转换方法。

在这种情况下,我建议您根据 GMT/UTC 时间戳字段的维度运行 GROUP BY,然后在代码中转换并显示本地时区的结果。

于 2012-09-18T18:32:52.333 回答
3

要将任何 TimeZone DateTime 字符串转换为 UTC,可以PARSE_TIMESTAMP使用.TIMESTAMPBigQuery

例如,要将 IST(印度标准时间)字符串转换为 UTC,请使用以下命令:

SAFE.PARSE_TIMESTAMP("%a %b %d %T IST %Y", timeStamp_vendor, "Asia/Kolkata")

这里PARSE_TIMESTAMP将 IST 字符串解析为 UTC TIMESTAMP(不是字符串)。添加SAFE为前缀可以处理错误/空值等。

要将其转换为 中的可读字符串格式BigQuery,请FORMAT_TIMESTAMP按如下方式使用:

FORMAT_TIMESTAMP("%d-%b-%Y %T %Z", SAFE.PARSE_TIMESTAMP("%a %b %d %T IST %Y", timeStamp_vendor, "Asia/Kolkata"))

此示例将采用格式的 IST 字符串Fri May 12 09:45:12 IST 2019并将其转换为12-May-2019 04:15:12 UTC.

将 IST 替换为所需的时区和Asia/Kolkata相关的时区名称,以实现您的时区的转换

于 2019-08-13T07:07:16.120 回答
-2

对我来说TIMESTAMP_SUBTIMESTAMP_ADD功能完成了这项工作。当需要将时间戳从 UTC 转换为 PST 时,我使用了:

TIMESTAMP_SUB(`timestamp`, INTERVAL 8 HOUR)
于 2021-03-31T11:21:22.480 回答