Местное время конвертирует время UTC в улей

Я много искал в Интернете, но не смог найти ответ. Вот мой вопрос:

Я пишу несколько запросов в Hive. У меня есть временная метка UTC, и я хотел бы изменить ее на время UTC, например, с учетом timestamp 1349049600, я хотел бы преобразовать ее в UTC, которое является 2012-10-01 00:00:00. Однако, если я использую встроенную функцию from_unixtime(1349049600) в Hive, я получаю локальное время PDT 2012-09-30 17:00:00.

Я понял, что есть встроенная функция, называемая from_utc_timestamp(timestamp, string timezone). Затем я попробовал это как from_utc_timestamp(1349049600, "GMT"), выход - это результат 1970-01-16 06: 44: 09.6, который абсолютно неверен.

Я не хочу постоянно менять часовой пояс улья, потому что есть другие пользователи. Так есть ли способ получить строку времени UTC от 1349049600 до "2012-10-01 00:00:00"? Большое спасибо!

Ответ 1

Насколько я могу судить, from_utc_timestamp() нужен аргумент строки даты, например "2014-01-15 11:21:15", а не значение unix seconds-since-epoch. Может быть, поэтому он дает нечетные результаты, когда вы передаете целое число?

Единственная функция Hive, которая имеет дело с секундами эпохи, кажется from_unixtime(), которая дает вам строку timestamp в часовом поясе сервера, которую я нашел в /etc/sysconfig/clock - "America/Montreal" в моем случае.

Таким образом, вы можете получить строку timestamp UTC через to_utc_timestamp(from_unixtime(1389802875),'America/Montreal'), а затем конвертировать в целевой часовой пояс с помощью from_utc_timestamp()

Все это кажется очень мучительным, особенно, чтобы связать ваш сервер TZ с вашим SQL. Жизнь была бы проще, если бы была функция from_unixtime_utc() или что-то еще.


Обновление: from_utc_timestamp() имеет дело с аргументом миллисекунды, а также с строкой, но затем неправильно преобразуется.

Когда я пытаюсь from_utc_timestamp(1389802875000, 'America/Los_Angeles'), он дает "2014-01-15 03:21:15", что неверно.
Правильный ответ "2014-01-15 08:21:15", который вы можете получить (для сервера в Монреале) через from_utc_timestamp(to_utc_timestamp(from_unixtime(1389802875),'America/Montreal'), 'America/Los_Angeles')

Ответ 2

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

#STATIC TZ deceleration     
to_utc_timestamp(from_unixtime(1389802875),'America/Montreal')

Сделайте снимок

#DYNAMIC TZ
select to_utc_timestamp(from_unixtime(1389802875), from_unixtime(unix_timestamp(), "z"));

Это просто использует формат вывода строки "from_unixtime", чтобы вернуть строку часового пояса (нижний регистр z)

Ответ 3

Используйте его следующим образом:

to_utc_timestamp(from_unixtime(timestamp),"PDT")

Ответ 4

В этом примере предлагается решение проблемы наличия жесткого значения системного часового пояса TZ в вашем коде куста. Он запускался с использованием hive 0.10.0 в среде Centos, с OpenJDK java версии 1.6. Поскольку это связано с манипулированием временем, то точные версии программного обеспечения могут иметь значение. В настоящее время система работает в EDT. Таблица tblFiniteZahl похожа на DUAL, но с примерно миллионом строк, из которых вы догадались, конечные числа. Но вы можете заменить любую таблицу как минимум на одну строку. Фокус в том, чтобы отформатировать время в локальном часовом поясе, но использовать формат z для захвата часового пояса, а затем извлечь это значение во время выполнения для перехода к функции to_utc_timestamp.

select D1,
       D1E,
       D1L,
       D1LT,
       D1LZ,
       to_utc_timestamp(D1LT, D1LZ) as D1UTC
from (
select D1,
       D1E,
       D1L,
       regexp_extract(D1L, '^([^ ]+[ ][^ ]+)[ ](.+)$', 1) as D1LT,
       regexp_extract(D1L, '^([^ ]+[ ][^ ]+)[ ](.+)$', 2) as D1LZ
from (
select D1,
       D1E,
       from_unixtime(D1E, 'yyyy-MM-dd HH:mm:ss z') as D1L
from (
select D1,
       unix_timestamp(D1,'yyyy-MM-dd HH:mm:ss Z') as D1E
from (
select '2015-08-24 01:15:23 UTC' as D1
from tblFiniteZahl
limit 1
      ) T1
      ) T2
      ) T3
      ) T4
;

Результат

D1 = 2015-08-24 01:15:23 UTC
DT3 = 1440378923
D1L = 2015-08-23 21:15:23 EDT
D1LT = 2015-08-23 21:15:23
D1LZ = EDT
D1UTC = 2015-08-23 21:15:23

Это иллюстрирует, что to_utc_timestamp принимает второй аргумент EDT.

Ответ 5

Я пошел в currentmillis.com и вставил 1349049600, не понимая, что это действительно секунды. И действительно, это вернуло 1970-01-16 в день, что означает, что функция, которую вы предложили: from_utc_timestamp фактически принимает миллисекунды в качестве первого параметра? Может быть, вы можете попробовать еще раз с from_utc_timestamp(1349049600000, "GMT")?