Как преобразовать метку времени Java, хранящуюся как bigint, в метку времени в Presto?

Мне не повезло с поиском этого в течение пары дней.

Если моя схема avro для данных в таблице улья:

{
  "type" : "record",
  "name" : "messages",
  "namespace" : "com.company.messages",
  "fields" : [ {
    "name" : "timeStamp",
    "type" : "long",
    "logicalType" : "timestamp-millis"
  }, {
  …

и я использую presto, чтобы запросить это, я не получаю отформатированные метки времени.

select "timestamp", typeof("timestamp") as type,
current_timestamp as "current_timestamp", typeof(current_timestamp) as current_type
from db.messages limit 1
timestamp     type   current_timestamp                  current_type
1497210701839 bigint 2017-06-14 09:32:43.098 Asia/Seoul timestamp with time zone

Я думал, что преобразовать их в метки времени с точностью до миллисекунды не составит труда, но я обнаружил, что у меня нет четкого способа сделать это.

select cast("timestamp" as timestamp) from db.messages limit 1
line 1:16: Cannot cast bigint to timestamp

Также они изменили приведение метки времени presto, чтобы всегда предполагать, что источник находится в секундах. https://issues.apache.org/jira/browse/HIVE-3454

Поэтому, если я использовал from_unixtime(), мне пришлось бы сократить миллисекунды, иначе это даст мне очень отдаленную дату:

select from_unixtime("timestamp") as "timestamp" from db.messages limit 1
timestamp  
+49414-08-06 07:15:35.000

Наверняка кто-то другой, кто работает с Presto чаще, знает, как правильно выразить конверсию. (Я не могу перезапустить серверы Presto или Hive, чтобы установить часовой пояс в UTC, кстати).


person dlamblin    schedule 14.06.2017    source источник


Ответы (2)


Я не нашел прямого преобразования из метки времени Java (количество миллисекунд с 1970 года) в метку времени, но это можно сделать с помощью to_unixtime и добавления миллисекунд в качестве интервала:

presto> with t as (select cast('1497435766032' as bigint) a)
     -> select from_unixtime(a / 1000) + parse_duration(cast((a % 1000) as varchar) || 'ms') from t;
          _col0          
-------------------------
 2017-06-14 12:22:46.032 
(1 row)

(правда громоздко, но работает)

person Piotr Findeisen    schedule 14.06.2017

выберите from_unixtime (cast (event_time as bigint) / 1000000) + parse_duration (cast ((cast (event_time as bigint)% 1000) as varchar) || 'ms') из ограничения TableName 10;

person Rajiv Singh    schedule 16.04.2018
comment
спасибо, но я не думаю, что понимаю, что это значит. Похоже, вы приводите время в секундах, а затем добавляете остаток миллисекунд. Но теперь меня запутали, почему первый разработчик или больше 1000. - person dlamblin; 17.04.2018