我的要求与我阅读标题的方式相同。如何将纪元时间戳作为文本转换为真实时间戳。就我而言,我从 json 对象中提取了一个。所以我最终得到了一个时间戳作为毫秒的文本
'1528446110978'
(格林威治标准时间:2018 年 6 月 8 日星期五上午 8:21:50.978)
这是我尝试过的。只是后者(ts_ok_with_ms)是完全正确的。
SELECT
data->>'expiration' AS expiration,
pg_typeof(data->>'expiration'),
-- to_timestamp(data->>'expiration'), < ERROR: function to_timestamp(text) does not exist
to_timestamp(
(data->>'expiration')::int8
) AS ts_wrong,
to_timestamp(
LEFT(
data->>'expiration',
10
)::int8
) AS ts_ok,
to_timestamp(
LEFT(
data->>'expiration',
10
)::int8
) + (
CASE
WHEN LENGTH(data->>'expiration') = 13
THEN RIGHT(data->>'expiration', 3) ELSE '0'
END||' ms')::interval AS ts_ok_with_ms
FROM (
SELECT '{"expiration": 1528446110978}'::json AS data
) dummy
这是返回的(转置)记录:
expiration 1528446110978
pg_typeof text
ts_wrong 50404-07-12 12:09:37.999872+00
ts_ok 2018-06-08 08:21:50+00
ts_ok_with_ms 2018-06-08 08:21:50.978+00
我确定我忽略了一个更简单的版本,即如何从 json 对象中的时间戳字符串获取带有 ms (ts_ok_with_ms) 的真实时间戳,但我希望这仍然会有所帮助。
更新:为了您的方便,这里有一个功能。
CREATE OR REPLACE FUNCTION data.timestamp_from_text(ts text)
RETURNS timestamptz
LANGUAGE SQL AS
$$
SELECT to_timestamp(LEFT(ts, 10)::int8) +
(
CASE
WHEN LENGTH(ts) = 13
THEN RIGHT(ts, 3) ELSE '0'
END||' ms'
)::interval
$$;