Местное время конвертирует время 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")
?