web-dev-qa-db-fra.com

Conversion de l'heure locale en heure UTC dans la ruche

J'ai beaucoup cherché sur Internet mais je n'ai pas trouvé de réponse. Voici ma question:

J'écris des requêtes dans Hive. J'ai un horodatage UTC et je souhaite le changer en heure UTC. Par exemple, étant donné l'horodatage 1349049600, je souhaite le convertir en heure UTC, à savoir le 2012-10-01 00:00:00. Toutefois, si j’utilise la fonction intégrée from_unixtime(1349049600) dans Hive, j’ai l’heure PDT locale 2012-09-30 17:00:00. 

J'ai réalisé qu'il existe une fonction intégrée appelée from_utc_timestamp(timestamp, string timezone). Ensuite, je l’ai essayé comme from_utc_timestamp(1349049600, "GMT"), la sortie est 1970-01-16 06: 44: 09.6, ce qui est totalement incorrect. 

Je ne veux pas changer le fuseau horaire de Hive de manière permanente car il y a d'autres utilisateurs. Alors, est-il possible d'obtenir une chaîne d'horodatage UTC de 1349049600 à "2012-10-01 00:00:00"? Merci beaucoup!!

11
Iam619

Autant que je sache, from_utc_timestamp() a besoin d'un argument de chaîne de date, tel que "2014-01-15 11:21:15", et non d'une valeur unix secondes-depuis-Epoch. C'est peut-être pourquoi il donne des résultats étranges lorsque vous passez un entier? 

La seule fonction Hive qui traite les secondes d’époque semble être from_unixtime() qui vous donne une chaîne d’horodatage dans le timezone server, que j’ai trouvée dans /etc/sysconfig/clock - "America/Montreal" dans mon cas.

Ainsi, vous pouvez obtenir une chaîne d'horodatage UTC via to_utc_timestamp(from_unixtime(1389802875),'America/Montreal'), puis la convertir dans votre fuseau horaire cible avec from_utc_timestamp().

Cela semble très pénible, en particulier de devoir connecter votre serveur TZ à votre code SQL. La vie serait plus facile s'il y avait une fonction from_unixtime_utc() ou quelque chose.


Update : from_utc_timestamp() traite un argument de milli secondes ainsi qu'une chaîne, mais la conversion est ensuite incorrecte. 

Quand j'essaie from_utc_timestamp(1389802875000, 'America/Los_Angeles') cela donne "2014-01-15 03:21:15" qui est faux.
La réponse correcte est "2014-01-15 08:21:15" que vous pouvez obtenir (pour un serveur à Montréal) via from_utc_timestamp(to_utc_timestamp(from_unixtime(1389802875),'America/Montreal'), 'America/Los_Angeles')

14
patricksurry

Hey, je voulais juste ajouter quelque chose ici, je suggérerais d’essayer d’automatiser le fuseau horaire du système. Donc au lieu de statiquement 

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

Donnez un coup de feu

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

Cela utilise simplement le format de sortie de chaîne de "from_unixtime" pour renvoyer la chaîne de fuseau horaire (minuscule z)

4
dedricF

Utilisez-le comme ceci:

to_utc_timestamp(from_unixtime(timestamp),"PDT")

2
Akshat Singhal

Cet exemple fournit une solution au problème de la présence d'une valeur câblée du fuseau horaire du système TZ dans votre code Hive. Il a été exécuté à l'aide de Hive 0.10.0 dans un environnement Centos, avec OpenJDK Java version 1.6. Parce que cela implique une manipulation du temps, ces révisions de logiciels précises peuvent avoir de l'importance. Actuellement, le système fonctionne en mode EDT. Le tableau tblFiniteZahl ressemble à un DUAL, mais avec environ un million de lignes, vous l’avez deviné, des nombres finis. Mais vous pouvez remplacer n'importe quelle table par au moins 1 ligne. L'astuce consiste à formater l'heure dans un fuseau horaire local mais à utiliser le format z pour capturer le fuseau horaire, puis à extraire cette valeur à l'exécution pour la transmettre à la fonction 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
;

Le résultat est

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

Cela montre que l’horodatage to_utc_ prend un deuxième argument d’EDT.

1
George Carrette