2017-08-01 29 views
0

空港での作業と同じように、DBに日付を表​​示させようとしています。たとえば、テキサスにいる場合、東海岸に飛行する必要がある場合、空港後継者は現地時間に離陸時刻と着陸時刻を表示します。たとえば、ダラスからニューヨークへのフライトでは、その地域の現地時間で時間が表示されます。oracle dbセッションとデータベースのタイムゾーンの変更、セッションゾーンの変更が行われない

Marquis in Dallas :  Takeoff time : 8AM Landing time: 10AM 
Marquis in New York: Takeoff time : 9AM Landing time: 11AM 

これを実行するために、DBは時刻をUTCで保存すると考えました。 TIMESTAMPにはゾーンが関連付けられていないことが分かっていますが、ゾーンにが添付されたに時間を節約することができます - 私の考えは、何らかの計算が変換それをUTCに変換します。しかし、下の私の小さなテストによると、これは起こっていないようです。私はセッション時間ゾーンを何に設定しても、日付は同じままです。

TIAのセッションでタイムゾーンを変更する

SQL> create table toast (t timestamp); 
Table created. 


SQL> insert into toast values (TIMESTAMP '2019-09-23 16:03:11 US/Eastern'); 
1 row created. 


SQL> select dbtimezone from dual; 
DBT 
--- 
UTC 

SQL> select sessiontimezone from dual; 
SESSIONTIMEZONE 
--------------------------------------------------------------------------- 
-04:00 


SQL> select * from toast; 
T 
--------------------------------------------------------------------------- 
23-SEP-19 04.03.11.000000 PM 

はまだ同じ日付

SQL> alter session set time_zone = 'America/Chicago'; 
Session altered. 

SQL> select sessiontimezone from dual; 
SESSIONTIMEZONE 
--------------------------------------------------------------------------- 
America/Chicago 

SQL> select * from toast; 
T 
--------------------------------------------------------------------------- 
23-SEP-19 04.03.11.000000 PM 

再びそれを変え、同じ結果

SQL> alter session set time_zone = 'Pacific/Auckland'; 
Session altered. 


SQL> select * from toast; 
T 
--------------------------------------------------------------------------- 
23-SEP-19 04.03.11.000000 PM 

を取得ではなく、時間を使用してそれを変更し、更新

SQL> SQL> alter session set time_zone = '-3:00'; 
Session altered. 


SQL> select sessiontimezone from dual; 
SESSIONTIMEZONE 
--------------------------------------------------------------------------- 
-03:00 


SQL> select * from toast; 
T 
--------------------------------------------------------------------------- 
23-SEP-19 04.03.11.000000 PM 

その詳細な応答のための 本当にありがとうございました@Alexプールを同じ結果を得ました!

私はHibernate、Java、Oracleで作業していましたが、Hibernateを使用して時間ベースのデータを保存する際に問題を抱えていました(この記事では、JAVA Calendarクラスを使用してソリューションをフォーマットしています)。記事はここにあります:How To Handle Oracle TimeStamp with TimeZone from Java私はまた、あなたが以前に "tirade"について言及した論文(と他の記事も)を見ていました。彼らはTIMESTAMPとLOCAL TIMEZONEの使用を止めてしまったようです。この情報のために私はちょっとTIMESTAMPを固執しようとしていました:-)しかし、TIMESTAMP WITH TIMEZONEのオプションもあります。

このOracleタイプの使用に関するご意見はありますか?

答えて

4

あなたはデータタイプを誤解しています。あなたが指摘したように、タイムスタンプにはタイムゾーンは保存されませんが、ではなく、では、「ゾーンに接続されたDBに時間を節約できます」ということができます。

あなたは:

insert into toast values (TIMESTAMP '2019-09-23 16:03:11 US/Eastern'); 

あなたがやっているかのように、プレーンなタイムスタンプにリテラル値の暗黙的な変換を行っている。

insert into toast values (cast (TIMESTAMP '2019-09-23 16:03:11 US/Eastern' as timestamp)); 

を元ゾーン情報が保持されるかまたは利用できません。元のタイムゾーン情報は破棄されるだけです(UTCなどに変換されることはありません)。

select TIMESTAMP '2019-09-23 16:03:11 US/Eastern', 
    cast (TIMESTAMP '2019-09-23 16:03:11 US/Eastern' as timestamp) 
from dual; 

TIMESTAMP'2019-09-2316:03:11US/EASTERN' CAST(TIMESTAMP'2019-09-2316: 
--------------------------------------- ---------------------------- 
23-SEP-19 16.03.11.000000000 US/EASTERN 23-SEP-19 16.03.11.000000000 

文字通りあなたのタイムスタンプから元の値は、タイムゾーンを示しています。キャスト値にタイムゾーン情報がありません。

セッションタイムゾーンを変更しても、影響を受けるタイムゾーン情報がないため、表示されているように、平文timestampには影響しません。影響を受けるデータタイプはtimestamp with time zoneまたはtimestamp with local time zoneにする必要があります。

あなたの場合、最終的に異なるタイムゾーンで2つの値を扱うので、セッションタイムゾーンを使用するだけでは本当に役に立ちません。明示的に指定領域とのいずれか、

create table toast (depart timestamp with time zone, 
    arrive timestamp with time zone); 

insert into toast (depart, arrive) 
values (TIMESTAMP '2019-09-23 08:00:00 US/Central', 
    TIMESTAMP '2019-09-23 11:00:00 US/Eastern'); 

alter session set time_zone = 'UTC'; 

Session altered. 

select to_char(depart, 'HH24:MI TZR') as depart, 
    to_char(arrive, 'HH24:MI TZR') as arrive 
from toast; 

DEPART         ARRIVE         
-------------------------------------- -------------------------------------- 
08:00 US/CENTRAL      11:00 US/EASTERN      

をして、地元の空港/表示時間帯with datetime expressionsに調整します:あなたは、出発/到着空港のタイムゾーンを意識した時間を格納することができ

select to_char(depart at time zone 'US/Central', 'HH24:MI TZR') as depart, 
    to_char(arrive at time zone 'US/Central', 'HH24:MI TZR') as arrive 
from toast; 

DEPART         ARRIVE         
-------------------------------------- -------------------------------------- 
08:00 US/CENTRAL      10:00 US/CENTRAL      

select to_char(depart at time zone 'US/Eastern', 'HH24:MI TZR') as depart, 
    to_char(arrive at time zone 'US/Eastern', 'HH24:MI TZR') as arrive 
from toast; 

DEPART         ARRIVE         
-------------------------------------- -------------------------------------- 
09:00 US/EASTERN      11:00 US/EASTERN      

あなたは確信していた場合やローカル・セッションのタイムゾーンを経由して、それは正しいです:

alter session set time_zone = 'US/Central'; 

select to_char(depart at local, 'HH24:MI TZR') as depart, 
    to_char(arrive at local, 'HH24:MI TZR') as arrive 
from toast; 

DEPART         ARRIVE         
-------------------------------------- -------------------------------------- 
08:00 US/CENTRAL      10:00 US/CENTRAL      

alter session set time_zone = 'US/Eastern'; 

select to_char(depart at local, 'HH24:MI TZR') as depart, 
    to_char(arrive at local, 'HH24:MI TZR') as arrive 
from toast; 

DEPART         ARRIVE         
-------------------------------------- -------------------------------------- 
09:00 US/EASTERN      11:00 US/EASTERN      

プラーイで行うことができ、しかしUTCとの時間を格納する方が良いかもしれn個のタイムスタンプは、まだあなたが好む場合 - そのすべてが格納されている値は常にUTCであると仮定し - そして、手動またはsys_extract_utc()で、UTCに元の回を変換:

create table toast (depart timestamp, arrive timestamp); 

insert into toast (depart, arrive) 
values (sys_extract_utc (TIMESTAMP '2019-09-23 08:00:00 US/Central'), 
    sys_extract_utc (TIMESTAMP '2019-09-23 11:00:00 US/Eastern')); 

... 

alter session set time_zone = 'US/Eastern'; 

select to_char(from_tz(depart, 'UTC') at local, 'HH24:MI TZR') as depart, 
    to_char(from_tz (arrive, 'UTC') at local, 'HH24:MI TZR') as arrive 
from toast; 

DEPART         ARRIVE         
-------------------------------------- -------------------------------------- 
09:00 US/EASTERN      11:00 US/EASTERN      

しかし領域を含むかもしれない方が安全です:

create table toast (depart timestamp with time zone, 
    arrive timestamp with time zone); 

insert into toast (depart, arrive) 
values (TIMESTAMP '2019-09-23 08:00:00 US/Central' at time zone 'UTC', 
    TIMESTAMP '2019-09-23 11:00:00 US/Eastern' at time zone 'UTC'); 

... 

alter session set time_zone = 'US/Eastern'; 

select to_char(depart at local, 'HH24:MI TZR') as depart, 
    to_char(arrive at local, 'HH24:MI TZR') as arrive 
from toast; 

DEPART         ARRIVE         
-------------------------------------- -------------------------------------- 
09:00 US/EASTERN      11:00 US/EASTERN      

しかし、あなたはtimestamp with local time zoneを使用する場合は一種の両方の最高の取得、より簡単に、そしてあなたが入力時間を変換する方法のregarless:

create table toast (depart timestamp with local time zone, 
    arrive timestamp with local time zone); 

insert into toast (depart, arrive) 
values (TIMESTAMP '2019-09-23 08:00:00 US/Central', 
    TIMESTAMP '2019-09-23 11:00:00 US/Eastern' at time zone 'UTC'); 

alter session set time_zone = 'UTC'; 

select to_char(depart, 'HH24:MI TZR') as depart, 
    to_char(arrive, 'HH24:MI TZR') as arrive 
from toast; 

DEPART         ARRIVE         
-------------------------------------- -------------------------------------- 
13:00 UTC        15:00 UTC        

alter session set time_zone = 'US/Central'; 

select to_char(depart, 'HH24:MI TZR') as depart, 
    to_char(arrive, 'HH24:MI TZR') as arrive 
from toast; 

DEPART         ARRIVE         
-------------------------------------- -------------------------------------- 
08:00 US/CENTRAL      10:00 US/CENTRAL      

alter session set time_zone = 'US/Eastern'; 

select to_char(depart, 'HH24:MI TZR') as depart, 
    to_char(arrive, 'HH24:MI TZR') as arrive 
from toast; 

DEPART         ARRIVE         
-------------------------------------- -------------------------------------- 
09:00 US/EASTERN      11:00 US/EASTERN      

(ALS oデータ型オプションの詳細についてはTony’s Tirade against TIMESTAMP WITH TIME ZONEをお読みください)

+0

優秀な回答 –

+0

@Alex Pooleは詳細な回答にとても感謝しています!私はmsgを次の質問で更新しました。私が前に触れた論文を見ていました。私は他の記事も見ました。基本的には、TIMESTAMPをローカルタイムゾーンで使用するように思われました(?)もしそうなら、TIMESTAMP WITH TIMEZONEはTIMESTAMPとローカルタイムゾーンの代わりになるでしょうか? TIA –

+0

@CaseyHarrils - あなたはTonyの記事の表の下の箇条書きを私とは非常に異なって解釈しているに違いない。 「異なるタイムゾーンを使用してデータをコピーするときは、TIMESTAMPを ローカル時間ゾーンで使用する」と「TIMESTAMPまたはタイムゾーンでタイムゾーンを使用しないでください」を使用してください。これらのすべてに問題はありますが、「現地時間帯のタイムスタンプ」は、あなたがやっていることのために最もシンプルで(トーンの仕事は)上に示したように 'タイムスタンプ 'をつけてすべてをUTCに強制することもできますが、おそらく航空の一般的なアプローチです。 –

1

はこれを試してみてください:TIME ZONE WITH TIMESTAMPと同様に

create table toast (t timestamp WITH LOCAL TIME ZONE); 

、データが保存され、検索されたとき 試合に、クライアントのタイムゾーンを調整し、データベースのタイムゾーンに正規化 であることを除いて。

関連する問題