我将一些日期时间类型列作为字符串推入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
我想计算时差(以秒或毫秒为单位)。
答案 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;