2017-11-22 18 views
-1

「22 -NOV-17 05.33.51.937000000 PM」のような形式で、サーバーのデフォルトタイムゾーンCSTで時刻を保存しています。私たちは、多くの場所で時間の半分を比較しています。だから、CSTからCDTとCSTへのCDTは、データベースの検索に時間帯を特定できないため、問題に直面しています。それで、CSTの時間比較をCDTとCDTとCSTの時間変更に壊しています。CST/CDTタイムゾーンの変更の問題

タイムゾーン付きのストアのようなストアロジックを変更することはできません。また、UTCタイムゾーンで保存することもできません。これは、多くの場所で既存のロジックを破壊するためです。

したがって、'22 -NOV-17 05.33.51.937000000 PM '形式のデータベースに格納されている、CSTやCDTのような日付のタイムゾーンを識別する方法はありません。

+1

これを文字列として保存していますか?それとも、あなたのクライアントがタイムスタンプ値を表示しているのかということですか?日付とタイムスタンプは内部形式で保存されますが、表示されているようなものではありません。 –

+2

'CST'と' CDT'とは何ですか? ( 'CST'、 'C​​DT')またはTZABBREV IN( 'CST'、 'C​​DT'); ' –

+1

秋には、あなたが設定した秋には、TZNAMEのTZNAMEを使用して、私たちは後ろに時計を戻し、再び同じ時間を繰り返します。つまり、その時間内の時間(2倍)があいまいであることを意味します.CSTかCDTかはわかりません。他のすべての時間はあなたが見つけることができます。 –

答えて

3

我々は

は、私たちがタイムスタンプとして保存されているあなたのコメント

と意味がないような'22 -NOV-17 05.33.51.937000000 PM」形式で時間を記憶していますデータベース

Oracleデータベースでは、TIMESTAMPにはフォーマットがありません。データベースには、年を表す11バイトとしてデータベースに格納されます(2バイト)、月、日、時、分、秒(それぞれ1バイト)および小数点以下の秒(4バイト)。データベースと話すために使用しているインタフェース(SQL/Plus、SQL Developer、Toad、Java、PHPなど)がユーザー、ユーザーに表示することを決定したときに、そのインタフェースが文字列としてフォーマットします(ただし、データベースではフォーマットなしのバイトとして保持されます)。

SELECT value FROM NLS_SESSION_PARAMETERS WHERE parameter = 'NLS_TIMESTAMP_FORMAT'; 

をまた使用して、デフォルトの書式を変更します:

ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SSXFF9'; 

それともTIMESTAMP WITH TIME ZONE

ためのあなたは、あなたが使用して、デフォルトの形式を見つけることができますSQL/PlusまたはSQL Developerを使用していると仮定すると、

ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT = 'YYYY-MM-DD HH24:MI:SSXFF9 TZR'; 

です「22 -NOV-17 05.33.51.937000000 PM」形式のデータベースに格納された、CSTやCDTのような日付のタイムゾーンを特定する方法はあります。

いいえ、それから来た場所のタイムスタンプのソースを識別し、示すことができる任意の他のメタデータなしで(すなわち、にマッピングすることができるデータを入力したユーザーへのリンク別の列があります物理的な場所および時間帯)、それがどのタイムゾーンから来たのかを判断することは不可能である。 TIMESTAMP WITH TIME ZONE

  • 変更データベースの列を、タイムゾーンを格納します。:

    あなたはする必要があります。どちらかまたは

  • すべての値を保存するときに同じタイムゾーンに変換します。
+0

ありがとう@ MT0、タイムゾーンでタイムスタンプを保存した後、検索時にjava/hibernateが自動的にタイムゾーンを異常にするか、何か追加操作を行う必要がありますか? –

+0

@ChiragKathiriya申し訳ありませんが、私はHibernateを使用していないので、それに答えることができません。 – MT0

+0

@ChiragKathiriya「[Hibernate 3.3.2GAを使用してTIMESTAMPをTIME ZONEでJavaデータ型にマップするにはどうすればよいですか?」](https://stackoverflow.com/q/4078520/1509264)または「日付/ JPAとHibernateのUTCタイムゾーンでの時刻とタイムスタンプ "](https://stackoverflow.com/q/508019/1509264)。 – MT0

1

私はCSTとCDTで、北米中部標準時と夏時間(レイニー・リバー、シカゴ、メキシコ(市)など)を想定しています。このあいまい性については、後で詳しく説明します。

すべての時間の99.977%で、標準時か夏時間かを知ることはかなり簡単です。 DSTから標準時間への移行の2時間からの唯一の時間はあいまいであり、コメントで述べたように、このあいまいさを解決する正しい方法であるタイムスタンプから知る方法はありません。

java.timeは、この答えは、あなたがまだjava.timeを使用することができます離れたJava 7からあなたを取ることなく、可能な未来に限りもJSRとして知られている最新のJavaの日付と時刻のAPIをお連れします-310。 ThreeTen BackportのJava 6と7にバックポートされているので、これを取得してプロジェクトに追加してください(Java 8以降にアップグレードする日まで)。

私はあなたの日時文字列形式をあなたの言葉にしています。我々それで何ができるか:

DateTimeFormatter storedFormatter = new DateTimeFormatterBuilder() 
      .parseCaseInsensitive() 
      .appendPattern("d-MMM-uu hh.mm.ss.SSSSSSSSS a") 
      .toFormatter(Locale.US); 
    ZoneId zone = ZoneId.of("America/Mexico_City"); 

    String storedTime = "22-NOV-17 05.33.51.937000000 PM"; 
    LocalDateTime dateTime = LocalDateTime.parse(storedTime, storedFormatter); 
    // First shot -- will usually be correct 
    ZonedDateTime firstShot = ZonedDateTime.of(dateTime, zone); 
    System.out.println(firstShot); 

これは印刷さ:00、時間は標準時間であることを意味している(:

2017-11-22T17:33:51.937-06:00[America/Mexico_City] 

をあなたはそれが-06のオフセットを選んだことを見ることができますCDTは-05:00です)。

月の省略形はすべて大文字であるため、フォーマッタに大文字小文字を区別しないように伝える必要がありました。 America/Mexico_Cityのタイムゾーンが適切でない場合は、America/Rainy_RiverやAmerica/Chicagoなど、より良いタイムゾーンを選択してください。秋

あいまいな時間が、私は一度標準時間とサマータイム(DST)の表示なしで日付時刻を含むログファイルを解析する必要がありました。時間は常に前進すると仮定していたため、標準時間に移行しても失敗し、ログファイルが1時間失われました。このケースでは、夏時間に遡って1時間後に飛び降りるまでの情報を標準時間に収めた情報を使って解決したかもしれません。似たようなものがあなたのために可能かどうかについて考えてみてください。

その他のオプションは、毎回DST時間を取るだけです(これは上記のコードが行うことです)。

我々は、少なくとも曖昧な時間を検出することができます:文字列が29-OCT-17 01.30.00.000000000 AMた場合

ZoneOffset standardOffset = ZoneOffset.ofHours(-6); 
    ZoneOffset dstOffset = ZoneOffset.ofHours(-5); 
    // check if in fall overlap 
    ZonedDateTime standardDateTime 
      = ZonedDateTime.ofLocal(dateTime, zone, standardOffset); 
    ZonedDateTime dstDateTime 
      = ZonedDateTime.ofLocal(dateTime, zone, dstOffset); 
    if (! standardDateTime.equals(dstDateTime)) { 
     System.out.println("Ambiguous, this could be in CST or CDT: " + dateTime); 
    } 

は今、私は

Ambiguous, this could be in CST or CDT: 2017-10-29T01:30 

ZonedDateTime.ofLocal()メッセージが提供を使用します取得、それならば、あいまいさを解決するためのオフセット日付と時刻の有効なオフセットです。春に

非既存倍

あなたの日付と時刻がクロックがDSTへの移行に前進させ、ギャップに該当する場合は同様に、我々は検出することができます:

// Check if in spring gap 
    if (! firstShot.toLocalDateTime().equals(dateTime)) { 
     System.out.println("Not a valid date-time, in spring gap: " + dateTime); 
    } 

この

Not a valid date-time, in spring gap: 2018-04-01T02:01 

このような値を拒否することをお勧めします。彼らは正しいことができません。

はCSTはキューバ標準時と中国標準時、オーストラリア中部標準時(北米、中米)中部標準時を参照することが

3文字のタイムゾーンの省略形を避けてください。 CDTは中央夏時間またはキューバ夏時間を意味する場合があります。 3文字と4文字の略語は標準化されておらず、非常にしばしばあいまいである。たとえば、アメリカ/ウィニペグの場合、地域/都市形式のタイムゾーンIDを使用することをお勧めします。