Big Query如何将字符串转换为日期

时间:2017-12-20 05:05:36

标签: google-bigquery

我将一些日期时间类型列作为字符串推入BQ。它们采用以下格式:Wed Dec 20 02:54:35 GMT 2017

我希望它们转换为正确的日期时间,所以我可以做一些操作,比如计算时间差,以毫秒为单位等等。我已经尝试过Date,强制转换,似乎没有任何工作。他们都给了null。

例如,请考虑这两个日期时间: startTime = Wed Dec 20 02:54:35 GMT 2017 endTime = Wed Dec 20 02:54:36 GMT 2017

我想计算时差(以秒或毫秒为单位)。

2 个答案:

答案 0 :(得分:2)

  

我希望将它们转换为正确的日期时间,以便我可以执行一些操作,例如以毫秒为单位计算时差等。

   

下面是BigQuery Standard SQL,理想情况下应该可以使用例如

#standardSQL
SELECT startTime, endTime,
  TIMESTAMP_DIFF(
    PARSE_TIMESTAMP('%a %b %d %H:%M:%S %Z %Y', endTime), 
    PARSE_TIMESTAMP('%a %b %d %H:%M:%S %Z %Y', startTime), 
    MILLISECOND
  ) diff_in_ms
FROM `yourproject.yourdataset.yourtable`   

您可以使用虚拟数据进行测试/播放,如下所示

#standardSQL
WITH `yourproject.yourdataset.yourtable` AS (
  SELECT 'Wed Dec 20 02:54:35 GMT 2017' startTime, 'Wed Dec 20 02:54:36 GMT 2017' endTime
)
SELECT startTime, endTime,
  TIMESTAMP_DIFF(
    PARSE_TIMESTAMP('%a %b %d %H:%M:%S %Z %Y', endTime), 
    PARSE_TIMESTAMP('%a %b %d %H:%M:%S %Z %Y', startTime), 
    MILLISECOND
  ) diff_in_ms
FROM `yourproject.yourdataset.yourtable`   
  

我完全可以完全删除时区

看起来您遇到PST问题 - 您可以尝试以下消除时区

#standardSQL
CREATE TEMP FUNCTION removeTZ(val STRING) AS (
  REGEXP_REPLACE(val, r'(\w+ \w+ \d{2} \d{2}:\d{2}:\d{2} )\w+ (\d{4})', '\\1\\2')
);
SELECT startTime, endTime,
  TIMESTAMP_DIFF(
    PARSE_TIMESTAMP('%a %b %d %H:%M:%S %Y', removeTZ(endTime)), 
    PARSE_TIMESTAMP('%a %b %d %H:%M:%S %Y', removeTZ(startTime)), 
    MILLISECOND
  ) diff_in_ms
FROM `yourproject.yourdataset.yourtable`   

仍然可以使用相同的虚拟数据进行测试/播放

#standardSQL
CREATE TEMP FUNCTION removeTZ(val STRING) AS (
  REGEXP_REPLACE(val, r'(\w+ \w+ \d{2} \d{2}:\d{2}:\d{2} )\w+ (\d{4})', '\\1\\2')
);
WITH `yourproject.yourdataset.yourtable` AS (
  SELECT 'Wed Dec 20 02:54:35 GMT 2017' startTime, 'Wed Dec 20 02:54:36 GMT 2017' endTime
)
SELECT startTime, endTime,
  TIMESTAMP_DIFF(
    PARSE_TIMESTAMP('%a %b %d %H:%M:%S %Y', removeTZ(endTime)), 
    PARSE_TIMESTAMP('%a %b %d %H:%M:%S %Y', removeTZ(startTime)), 
    MILLISECOND
  ) diff_in_ms
FROM `yourproject.yourdataset.yourtable`   

以上两个查询都返回相同的结果(当然)

startTime                       endTime                         diff_in_ms   
Wed Dec 20 02:54:35 GMT 2017    Wed Dec 20 02:54:36 GMT 2017    1000     

注意:第二种解决方案(具有时区消除)不依赖于预定义的位置/长度,因为时区可以具有不同的长度。相反,它使用正则表达式来识别时区并将其删除

答案 1 :(得分:1)

尝试使用PARSE_TIMESTAMP

SELECT
    PARSE_TIMESTAMP('%a %b %d %H:%M:%S %Z %Y', 'Wed Dec 20 02:54:35 GMT 2017')
FROM yourTable;

从上面SQL的详细程度可以看出,如果您需要将日期作为实际日期进行处理,将日期存储为文本很麻烦。相反,始终将日期/时间戳存储在正确的日期列中。

我们可以在没有时区的情况下尝试解析:

SELECT
    PARSE_TIMESTAMP('%a %b %d %H:%M:%S %Y',
        CONCAT(SUBSTR(col, 1, 20), SUBSTR(col, 25, 4)))
FROM yourTable;