2016-04-27 9 views
3

同じタイムゾーン内の同じマシンで実行されているブラウザ(JS)とJavaの日付/時刻/タイムゾーンの相違に関する質問があります。私はシステムがそのような問題を避けるために、タイムゾーン(主にUTC、Date.UTCを使用)に同意すべきであることを認識しています。それでも、私はこの例がうまくいくはずだと思った。差異のタイムゾーンブラウザとJava

このため、私はブラウザ(Chrome)でいくつかの日付を作成し、同じミリ秒を使用してJavaで日付を作成しました。

ここに私が理解していない例があります。私の理解を助けてください。

クローム(JavaScriptの):

new Date(1980,9,10,0,0,0,0) Fri Oct 10 1980 00:00:00 GMT+0200 (Mitteleuropäische Sommerzeit) The millis are: 339976800000

のJava:

new Date(339976800000l) Thu Oct 09 23:00:00 CET 1980

JavaはCETはJavaScriptをCESTを適用wheras適用されますのでご注意ください。

+2

23:00 CET == 00:00 CEST(冬と夏の時間の差)。 – assylias

+0

慎重に質問を読んでください。なぜこのような状況でJa​​vaがCESTの代わりにCETを使用するのだろうかと思います。 – chris1069603

+1

Javaで使用する実際のコードを入力してください。 7つのパラメータを取る 'java.util.Date'のコンストラクタはありません。また、年と月のオフセットを差し引く必要があります。また、両方の環境で設定したタイムゾーンを表示してください。 –

答えて

1

TL; DR

以前DSTが9月の最後の日曜日に終了した1980年と2016年

間で変更Daylight Saving Time (DST)の定義は、後で10月の最後の日曜日に終了するように変更。

詳細な回答

パズルの欠けている部分は、あなたの計算に使用される特定の時間帯を知ることです。 あなたの質問とサンプルコードは、使用されたタイムゾーンを正確に教えてくれません。ここでは、DSTの定義が変更されているため、Europe/Berlin(ドイツ語ではっきりとローカライズされたテキストの使用に基づく)と同様のタイムゾーンを使用しているものとします。

CETCESTは、実際にタイムゾーンではありません。そのような略語は標準化されておらず、独自のものでもありません。 避けてください。

代わりにtz databaseに定義されているようにproper time zone namesを使用してください。 A true time zoneは、offset-from-UTCと、夏時間(DST)などの過去、現在、および将来の異常を処理するための一連のルールを加えたものです。

タイムゾーンのルールが変更され、驚くほど頻繁に変更されます。退屈な政治家、私は思います。

たとえば、Europe/Berlinは、1980年に9月の最後の日曜日にDSTを終了するように変更されました。したがって、DSTは1980年10月のあなたの日付には当てはまりません。1996年以来、DSTを9月よりむしろ10月最後の日曜日に延長するEU規則が適用されます。したがって、DST となります。

質問内のコードは実際には月が「10」を意味する月「9」を使用します。古いjava.util.Dateクラスの多くの問題の1つは、ゼロベースのカウント、0 = 1月によって数えられることです。古い日時クラスを避けるための多くの理由の1つ。対照的に、Javaでは。10月の月の数値は実際には10であり、Monthの定数を使用するとさらに明確になります。

ちなみにjava.util.Dateのもう1つの貧弱なデザインの選択肢は、Question内のconstructing a Date object as you didの場合、JVMの現在のデフォルトタイムゾーンが適用され、結果がUTCに戻されます。これは、コードを実行したときに使用中のタイムゾーンを報告しなかったため、さらに複雑になります。

ところで、JavaScriptはほぼすべての開発プラットフォームと同様に、日時制作のサポートが貧弱です。可能であれば、Javaとその組み込みのjava.timeフレームワークを使用してみてください。 Oracle Tutorialを参照してください。次のコード例では、動作中のjava.timeを見ることができます。 1980年10月10日、Europe/Berlinは2016年になります。

ZoneId zoneId = ZoneId.of ("Europe/Berlin");; 

ZonedDateTime zdt_1980 = ZonedDateTime.of (1980 , Month.OCTOBER.getValue() , 10 , 0 , 0 , 0 , 0 , zoneId); 
long seconds_1980 = zdt_1980.toEpochSecond(); 

ZonedDateTime zdt_2016 = ZonedDateTime.of (2016 , Month.OCTOBER.getValue() , 10 , 0 , 0 , 0 , 0 , zoneId); 
long seconds_2016 = zdt_2016.toEpochSecond(); 

コンソールにダンプします。あなたはオフセットから、UTCという結果に表示することができます

System.out.println ("zoneId: " + zoneId); 
System.out.println ("zdt_1980: " + zdt_1980 + " | seconds_1980: " + seconds_1980); 
System.out.println ("zdt_2016: " + zdt_2016 + " | seconds_2016: " + seconds_2016); 

は現在、2時間進んUTC(+02:00)のために、古い時代に先駆けUTC(+01:00)の1時間から変更しました。違いはDSTの再定義のためです。

だから、これはあなたが1980年に「CET」を持っていますが、2016年のために得たCESTで2016 Sで「CEST」「夏」を意味し、「サマータイム」はDSTを意味理由を説明します。今年の2016年の10月のほとんどは「サマータイム」(DST)です。 1980年10月はDST/"CEST"ででなくでした。

するzoneid:ヨーロッパ/ベルリン

zdt_1980:1980-10-10T00:00 + 01:00 [ヨーロッパ/ベルリン] |秒_1980:339980400

zdt_2016:2016-10-10T00:00 + 02:00 [ヨーロッパ/ベルリン] | seconds_2016:1476050400

+0

すべての情報をありがとうございます。上記のコードはデモンストレーション目的でのみ使用されていました。クライアントとサーバーは同じタイムゾーンで実行されます。実際の問題はJSとJavaが過去の日付を別々に扱うことでした。 JSは現在のDSTルールのみを適用します。http://stackoverflow.com/questions/16946002/javascript-time-zone-is-wrong-for-past-daylight-saving-time-transition-rules – chris1069603

+0

@ chris1069603実際にあなたのJavaScriptとJavaで、どのタイムゾーンが適用されているかを判断するまで、実際に状況を診断することはできません。両方の場合にコードを追加してタイムゾーンを取得し、報告してください。それまでは、あなたは推測して推測しています。 Javaでは、['ZoneId.systemDefault()'](https://docs.oracle.com/javase/8/docs/api/java/time/ZoneId.html#systemDefault--)または['TimeZone]を呼び出すことができます。 getDefault() ']](http://docs.oracle.com/javase/8/docs/api/java/util/TimeZone.html#getDefault--)を参照してください。 JavaScriptについては、わかりません。 –

+0

それは確かにヨーロッパ/ベルリンです。添付されたリンクはJavascriptの動作を非常によく説明しています。質問をより明確にするために、あなたの意見に応じて質問を編集しました。コメントを読んだとき、最初は悲惨に失敗したように感じます。ごめんなさい。私たちはこれを他の人に役立ててくれることを願っています私にとっては、JavaとJSが異なるルールを適用することを実現することは大きな驚きでした – chris1069603