2017-02-13 1 views
0

J'ai une colonne timestamp dans ma table, je dérive une colonne nommée dt_skey de la colonne timestamp. Pour une explication claire, supposons que le nom de la colonne d'horodatage est time_column. Voici à quoi ressemble la colonne de temps 2017-02-05 03:33:50, dt_skey qui ressemble à ceci 20170205033350 qui n'est rien d'autre que de supprimer les symboles entre les deux.Comment puis-je convertir un horodatage au format gmt dans la ruche

Ma question ici: time_column est en est timezone, je veux le convertir au format gmt alors que je dérive dt_skey de celui-ci. La raison pour laquelle je veux faire ceci est l'horodatage qui sera converti au format gmt lorsque nous l'interrogerons via l'impala où dt_skey ne sera pas converti car il s'agit d'un type de données int. Je fais l'ingestion via la ruche où l'horodatage et la colonne dt_skey seront synchronisés lorsque nous interrogerons via la ruche. Pour le rapport et les utilisateurs, nous utilisons l'impala, donc je veux apporter des modifications à la colonne dt_skey de sorte que si l'utilisateur consulte l'impala, les deux colonnes doivent être synchronisées.

est inférieure à la sql j'utilise pour calculer dt_skey colonne sur une colonne d'horodatage:

cast(substr(regexp_replace(cast(time_column as string), '-',''),1,8) as int)as dt_skey 

la requête ci-dessus convertira cette 2017-02-02 07:32:51 dans ce 20170202.

S'il vous plaît aidez-moi à compenser le dt_skey au format GMT. J'apprécie également les solutions à travers l'étincelle.

+0

Pourquoi la balise 'mysql'? et êtes-vous sûr que "2017-02-05" devient "20170233" lorsque vous supprimez les tirets? –

+0

Mon tag sql est parce que la ruche utilise à peu près sql quires, et la date sera comme est juste enlevé les tirets entre les deux, je viens d'éditer la question s'il vous plaît voir le changement. Thankyou – Rob

Répondre

1

Dans Spark:

rdd = spark.sparkContext.parallelize([('2017-02-05 03:33:50',)]) 
df = spark.createDataFrame(rdd, ['EST']) 
df = df.withColumn('GMT', f.to_utc_timestamp(df['EST'], 'EST')) 
res = df.withColumn('YouWanna', f.date_format(df['GMT'], 'yyyyMMddHHmmss')) 
res.show(truncate=False) 

+-------------------+---------------------+--------------+ 
|EST    |GMT     |YouWanna  | 
+-------------------+---------------------+--------------+ 
|2017-02-05 03:33:50|2017-02-05 08:33:50.0|20170205083350| 
+-------------------+---------------------+--------------+ 

Ou dans la ruche:

select date_format(to_utc_timestamp('2017-02-05 03:33:50','EST'), 'yyyyMMddHHmmss') from dual 

Voulez-vous dire cela?

+0

Pourriez-vous s'il vous plaît jeter un oeil à la question suivante 'https://stackoverflow.com/questions/47518199/daylight-savings-time-issue-while-importing-data -de-mysql-à-étincelle/47518691 # 47518691' – User12345

0

vous ne doit ajouter 0 à votre champ comme:

SELECT datetimefield+0; 

SELECT CONVERT_TZ('2017-02-02 07:32:51','EST','GMT'); 

si CONVERT_TZ NULL retour, vous pouvez installer les tables de fuseau horaire comme:

mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql 

échantillon

mysql> SELECT CONVERT_TZ('2017-02-02 07:32:51','EST','GMT'); 
+-----------------------------------------------+ 
| CONVERT_TZ('2017-02-02 07:32:51','EST','GMT') | 
+-----------------------------------------------+ 
| 2017-02-02 12:32:51       | 
+-----------------------------------------------+ 
1 row in set (0,00 sec) 

mysql> 
mysql> SELECT DATE(TIMESTAMP('2017-02-02 07:32:51'))+0; 
+------------------------------------------+ 
| DATE(TIMESTAMP('2017-02-02 07:32:51'))+0 | 
+------------------------------------------+ 
|         20170202 | 
+------------------------------------------+ 
1 row in set (0,00 sec) 

mysql> select id, mydate, date(mydate), date(mydate)+0 from df; 
+----+---------------------+--------------+----------------+ 
| id | mydate    | date(mydate) | date(mydate)+0 | 
+----+---------------------+--------------+----------------+ 
| 1 | 2017-02-05 03:33:50 | 2017-02-05 |  20170205 | 
+----+---------------------+--------------+----------------+ 
1 row in set (0,00 sec) 

mysql> 

mysql> SELECT TIMESTAMP('2017-02-05 03:33:50')+0; 
+------------------------------------+ 
| TIMESTAMP('2017-02-05 03:33:50')+0 | 
+------------------------------------+ 
|      20170205033350 | 
+------------------------------------+ 
1 row in set (0,00 sec) 

mysql> 
mysql> select id, mydate, mydate+0 from df; 
+----+---------------------+----------------+ 
| id | mydate    | mydate+0  | 
+----+---------------------+----------------+ 
| 1 | 2017-02-05 03:33:50 | 20170205033350 | 
+----+---------------------+----------------+ 
1 row in set (0,00 sec) 

mysql> 
+0

Merci de partager cela, mais en changeant le format n'est pas mon problème Je veux convertir le format de temps modifié en fuseau horaire gmt. – Rob

+0

désolé, j'ai ajouter un échantillon convertir timezone dans ma réponse –

0

En supposant que vous voulez un Hive requête, voilà comment je convertir une colonne Ruche TimeStamp (en utilisant le fuseau horaire du système actuel) dans une Impala TimeStamp (en utilisant l'UTC qui est le même que GMT sauf GMT est désapprouvée).

CREATE TEMPORARY MACRO to_impala_timestamp(ts TIMESTAMP) 
    CAST(FROM_UNIXTIME(UNIX_TIMESTAMP(ts) +CAST(CAST(PRINTF('%tz', ts) AS FLOAT)*36.0 AS INT)) AS TIMESTAMP) 
; 
--## WARNING - do not use MACROs if your Hive version is below V1.3 (Apache, Horton) 
--## or below V1.1-CDH5.7.3, V1.1-CDH5.8.3, V1.1-CDH5.9.0 (Cloudera) 
--## cf. "HIVE-11432 Hive macro give same result for different arguments" 

Le PRINTF('%tz', ts) va extraire le fuseau horaire, en prenant soin de l'heure d'été dynamique - en supposant que les horodateurs vous traitez concernent le fuseau horaire du système utilisé par votre cluster Hadoop. Si c'est une TZ différente, vous devez adapter la macro en conséquence.

Vous pouvez le tester avec cette requête:

CREATE TABLE test_tz 
STORED AS Parquet 
AS 
SELECT CAST(ts AS STRING) AS initial_ts_as_string 
    , printf('%1$tz %1$tZ', ts) AS tzone_offset_and_code 
    , ts AS ts_for_hive 
    , to_impala_timestamp(ts) AS ts_for_impala 
FROM ... 

Notre groupe utilise le temps d'Europe centrale, et voilà comment le résultat montre Ruches ...

+--------------------------+--------------------+-----------------------------+-------------------------+ 
| initial_ts_as_string | tz_offset_and_code | ts_for_hive     | ts_for_impala   | 
+--------------------------+--------------------+-----------------------------+-------------------------+ 
| 2015-09-13 11:32:30.627 | +0200 CEST   | 2015-09-13 11:32:30.627  | 2015-09-13 13:32:30.0 | 
| 2015-12-10 12:27:01.282 | +0100 CET   | 2015-12-10 12:27:01.282  | 2015-12-10 13:27:01.0 | 
| 2016-05-17 15:49:06.386 | +0200 CEST   | 2016-05-17 15:49:06.386  | 2016-05-17 17:49:06.0 | 

... puis à Impala ...

+-------------------------+--------------------+-------------------------------+---------------------+ 
| initial_ts_as_string | tz_offset_and_code | ts_for_hive     | ts_for_impala  | 
+-------------------------+--------------------+-------------------------------+---------------------+ 
| 2015-09-13 11:32:30.627 | +0200 CEST   | 2015-09-13 09:32:30.627000000 | 2015-09-13 11:32:30 | 
| 2015-12-10 12:27:01.282 | +0100 CET   | 2015-12-10 11:27:01.282000000 | 2015-12-10 12:27:01 | 
| 2016-05-17 15:49:06.386 | +0200 CEST   | 2016-05-17 13:49:06.386000000 | 2016-05-17 15:49:06 | 

Notez que les millisecondes sont perdues lors de l'exécution de la conversion; ils pourraient être restaurés avec une astuce supplémentaire, mais en général, cela va au-delà du but.


Side note: pour formater un timestamp (ou date ou flotteur ou autre) dans une chaîne, la bonne vieille fonction Java PRINTF() est beaucoup plus pratique que d'utiliser le format par défaut, plus REGEXP_***() fonctions ...

0

Merci pour tous les solutions fournies

Toutes les réponses ici ont la solution partielle, en utilisant les ressources de réponse j'ai essayé la syntaxe ci-dessous et cela a fonctionné.

cast(substr(regexp_replace(to_utc_timestamp(timestamp_column, 'EST') ,'-',''),1,8) as int) as dt_skey 

Pour expliquer la syntaxe ci-dessus, voici comment ma colonne d'horodatage ressemble (aaaa-MM-JJ HH: mm: ss) "16/02/2017 12:20:21"

Après en exécutant la syntaxe ci-dessus ma sortie sera comme '20170216' qui est 'yyyyMMdd' regexp_replace fera l'expression régulière pour afficher seulement yyyyMMdd. to_utc_timestamp(timestamp_column, 'EST') convertira la colonne timestamp en fuseau horaire UTC.