2017-02-13 2 views
0

私は自分のテーブルにタイムスタンプ列を持っています。私はタイムスタンプ列からdt_skeyという名前の列を派生しています。明確な説明のために、タイムスタンプ列名をtime_columnと仮定してください。これは、time_columnが2017-02-05 03:33:50dt_skey列のように見え、20170205033350のようなもので、それは間にあるシンボルを削除するだけです。ハイブでタイムスタンプをgmt形式に変換するには

ここで私の質問:time_columnはest timezoneにありますが、私はそれをdt_skeyから派生させている間にgmt形式に変換したいと思います。私がこれをやりたい理由は、インラインでdt_skeyがintデータ型であるため変換されないimpalaを通して、タイムスタンプがgmt形式に変換されることです。私はハイブを介してクエリを実行すると、タイムスタンプとdt_skeyの列が同期するハイブを通して処理を行っています。報告目的と私たちはimpalaを使用するユーザーのため、dt_skey列を変更したいので、ユーザーがimpalaを調べると両方の列が同期している必要があります。上記のクエリは、この20170202にこの2017-02-02 07:32:51を変換します

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

:以下

は、私はタイムスタンプ列のうち、 dt_skey列を導出するために使用していたSQLです。

dt_skeyをGMT形式にオフセットするのを手伝ってください。私はまた、スパークを通じてソリューションを歓迎します。

+0

なぜ「mysql」タグですか?ダッシュを削除すると「2017-02-05」が「20170233」になることは確かですか? –

+0

私のsqlタグは、hiveがかなり多くのSQLクエリを使用しているため、日付はちょうどその間のダッシュを削除されますので、私はちょうど質問を編集してください。ありがとう – Rob

答えて

1

:あなたは次のようにタイムゾーンテーブルをインストールすることができます

SELECT datetimefield+0; 

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

CONVERT_TZリターンNULL場合スパーク中:

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| 
+-------------------+---------------------+--------------+ 

またはハイブで:

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

はこれを意味しますか?

+0

お願いします。次の質問をご覧ください。https://stackoverflow.com/questions/47518199/daylight-savings-time-issue-while-importing-data -from-mysql-to-spark/47518691#47518691' – User12345

0

あなただけのようなあなたのフィールドに0を追加する必要があります。

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

サンプル

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

共有していただきありがとうございますが、形式を変更することは私の問題ではありません。変更された形式の時刻をgmtのタイムゾーンに変換します。 – Rob

+0

申し訳ありませんが、私の答えにタイムゾーンのサンプルを追加しました –

0

それは私が(GMTは廃止さ除き、GMTと同じであるUTCを使用して)インパラタイムスタンプに(現在のシステムのタイムゾーンを使用して)ハイブタイムスタンプ列を変換する方法です、あなたはハイブ問い合わせをしたいと仮定。あなたが処理しているタイムスタンプがあなたのHadoopクラスタで使用されるシステムのタイムゾーンに関連していることを想定し-

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" 

PRINTF('%tz', ts)

は動的夏時間の世話をして、タイムゾーンを抽出します。異なるTZの場合は、それに応じてマクロを適応させる必要があります。

あなたはこのクエリでそれをテストすることができます。

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 ... 

は、当社のクラスタは、中央ヨーロッパ時間を使用し、それが結果はハイブに示した方法です...

+--------------------------+--------------------+-----------------------------+-------------------------+ 
| 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 | 

...その後インパラで...

+-------------------------+--------------------+-------------------------------+---------------------+ 
| 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 | 

変換の実行中にミリ秒が失われることに注意してください。彼らは追加のトリックで復元することができましたが、通常はそれを超えています。


サイドノート:...古き良きJavaのPRINTF()機能はデフォルトのフォーマットに加えてREGEXP_***()機能を使用するより方法がより実用的であり、文字列にすべてのための

0

感謝をタイムスタンプ(または日付またはfloatまたは何でも)をフォーマットします解決策を提供

すべての答えは、私は以下の構文を試して、それが働いた答えのリソースを使用して、部分的な解決策を持っています。

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

これは私のタイムスタンプ列がどのように見えるかである、上記の構文を説明するために(YYYY-MM-DD HH:MM:SS) "2017年2月16日午前12時20分21秒"

後上記の構文を実行すると、私の出力は 'yyyyMMdd'のような '20170216'になります。regexp_replaceは正規表現を使ってyyyyMMddだけを表示します。 to_utc_timestamp(timestamp_column, 'EST')は、タイムスタンプ列をUTCタイムゾーンに変換します。

関連する問題