web-dev-qa-db-ja.com

Oracle SQL:タイムスタンプをUTCに変換

次のような単純な選択クエリがありますが、地域の時間を取り戻していることに気付きました。 select文でUTCに変換するにはどうすればよいですか?

select myTimeStamp, MyName, MyBranch from tableA

結果:'27/03/2014 15:15:26 '' john '、' london '

Sys_extract_utc(myTimeStamp)を使用しようとしましたが、エラーがあります

sqlコマンドが正しく終了していません

myTimestampは 'date'型です。

13
Fearghal
select cast(mytimestamp as timestamp) at time zone 'UTC', 
       MyName, 
       MyBranch 
from tableA

mytimestampは実際にはdateであるため、キャストする必要があるタイムスタンプではありません。そうすることで、Oracleはmytimestampに格納されている情報がサーバーのタイムゾーンにあると想定します。そうでない場合は、Madhawasのソリューションを使用する必要があります。

17

タイプに応じて、myTimestampのデータ型が何であるかに応じてOracleがどのタイムゾーンから変換するかに関して、いくつかの落とし穴があります。

タイムゾーン付きのタイムスタンプ

It Just Works™。 a_horse_with_no_nameには正しい答えがあります。

ローカルタイムゾーンのタイムスタンプ

それは暗黙的にタイムゾーン付きタイムスタンプにキャストされ、その後It Just Works™になります。繰り返しますが、a_horse_with_no_nameがここにあります。

タイムスタンプ

これも暗黙的にtimestamp with time zoneにキャストされますが、デフォルトで割り当てられるタイムゾーンはsessionタイムゾーンです(databaseタイムゾーンとは対照的に)。

  • これの明示的な呼び出しは_myTimestamp at local_です。
  • 別の方法として(そしておそらく最も良い方法)、Madhawasのように実行し、_from_tz_関数を使用して、セッションのタイムゾーン以外の明示的なタイムゾーンで値を明示的に構築できます。

日付

上記のいずれかをdateにしようとすると、説明したように失敗します。

  • _myTimestamp at time zone 'UTC'_
    ORA-30084:タイムゾーン修飾子を持つ日時プライマリのデータ型が無効です

  • from_tz(myTimestamp, 'America/New_York')
    ORA-00932:一貫性のないデータ型:TIMESTAMPがDATEになると予想されます

ここでの解決策は、日付をtimestamp firstにキャストすることです。

_select from_tz(cast(myTimestamp as timestamp), 'America/New_York') from tableA
_

サンプルスクリプト

次のスクリプトは動作を示しています。私のシステムでは、dbtimezoneはUS/Centralであり、sessiontimezoneはGMT-05:00であることに注意してください。

一部のツールは結果のタイムスタンプを微妙な方法で変更することがわかっているため、特に_to_char_を使用して出力を変換します(特にタイムスタンプサポートが適切でない場合).

_alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS'
/
alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS'
/
alter session set nls_timestamp_tz_format = 'YYYY-MM-DD HH24:MI:SS TZR'
/

select dbtimezone
      ,sessiontimezone
      ,to_char(timestamp '2017-01-01 06:00:00') as ts
      ,to_char(timestamp '2017-01-01 06:00:00' at local) as ts_at_local
      ,to_char(timestamp '2017-01-01 06:00:00' at time zone dbtimezone) as ts_at_db
      ,to_char(timestamp '2017-01-01 06:00:00' at time zone sessiontimezone) as ts_at_session
 from dual
/
_

私のシステムでの出力は次のとおりです(読みやすくするために列形式に再フォーマットされています)。

_DBTIMEZONE          US/Central
SESSIONTIMEZONE     -05:00
TS                  2017-01-01 06:00:00
TS_AT_LOCAL         2017-01-01 06:00:00 -05:00
TS_AT_DB            2017-01-01 05:00:00 US/CENTRAL
TS_AT_SESSION       2017-01-01 06:00:00 -05:00
_
9

これにはタイムゾーンを知る必要があります。

SELECT myTimeStamp, from_tz(myTimeStamp, 'America/New_York') AT TIME ZONE 'UTC' utc FROM dual;
5
Madhawas

Oracle 19cからは、 TO_UTC_TIMESTAMP_TZ

SQL関数TO_UTC_TIMESTAMP_TZは、ISO 8601日付形式文字列をvarchar入力として受け取り、SQLデータ型TIMESTAMP WITH TIMEZONEのインスタンスを返します。入力をUTC時間(協定世界時、以前はグリニッジ標準時)に正規化します。 SQL関数TO_TIMESTAMP_TZとは異なり、新しい関数は入力文字列がISO 8601日付形式を使用し、タイムゾーンをUTC 0にデフォルト設定することを想定しています。

select TO_UTC_TIMESTAMP_TZ ( to_char(sysdate,'yyyy-mm-dd"T"HH:MI:SS') )  as utc 
   from dual;

 UTC
31-MAR-19 05.45.36.000000 AM +00:00
0
Kaushik Nayak