[解決済み] この2回(1927年)を引き算すると、なぜおかしな結果になるのでしょうか?
質問
次のプログラムを実行すると、1秒違いの時刻を参照する2つの日付文字列を解析して比較することができます。
public static void main(String[] args) throws ParseException {
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str3 = "1927-12-31 23:54:07";
String str4 = "1927-12-31 23:54:08";
Date sDt3 = sf.parse(str3);
Date sDt4 = sf.parse(str4);
long ld3 = sDt3.getTime() /1000;
long ld4 = sDt4.getTime() /1000;
System.out.println(ld4-ld3);
}
と出力されます。
353
なぜ
ld4-ld3
ではなく
1
(1秒のタイム差から予想されることですが)ではなく
353
?
日付を1秒後の時刻に変更すると。
String str3 = "1927-12-31 23:54:08";
String str4 = "1927-12-31 23:54:09";
次に
ld4-ld3
は、次のようになります。
1
.
Java のバージョンです。
java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
Dynamic Code Evolution Client VM (build 0.2-b02-internal, 19.0-b04-internal, mixed mode)
Timezone(`TimeZone.getDefault()`):
sun.util.calendar.ZoneInfo[id="Asia/Shanghai",
offset=28800000,dstSavings=0,
useDaylight=false,
transitions=19,
lastRule=null]
Locale(Locale.getDefault()): zh_CN
解決方法は?
上海では12月31日にタイムゾーンが変更されるのです。
参照 このページ は、1927年の上海の様子です。基本的に1927年末の真夜中に、時計は5分52秒戻りました。つまり、"1927-12-31 23:54:08" は実際には2回発生していて、Javaはこれを 後 そのローカルの日付/時刻の可能性のある瞬間 - だからこその違いです。
タイムゾーンにまつわる奇妙で素晴らしいエピソードがまたひとつ増えました。
EDIT プレスストップ! 歴史が変わる...
のバージョン2013aで再構築すると、元の質問と全く同じ挙動を示さなくなります。 TZDB . 2013aでは、結果は358秒となり、遷移時間は23:54:08ではなく、23:54:03となるのです。
私がこれに気づいたのは、野田時間でこのような質問を集めているためで、その形は ユニットテスト ... このテストは現在変更されていますが、これは、過去のデータでさえ安全ではないことを示すものです。
EDITです。 また歴史が変わった...。
TZDB 2014fでは、変更時刻が1900-12-31に移動し、わずか343秒の変更になりました(なので、その間の時間は
t
と
t+1
は344秒です、おわかりでしょうか)。
EDITです。 1900時の遷移に関する質問に答えると、Javaのタイムゾーンの実装では、次のように扱われるようです。 すべて タイムゾーンは、UTC 1900の開始前のどの瞬間も、単にその標準時であるとして扱われます。
import java.util.TimeZone;
public class Test {
public static void main(String[] args) throws Exception {
long startOf1900Utc = -2208988800000L;
for (String id : TimeZone.getAvailableIDs()) {
TimeZone zone = TimeZone.getTimeZone(id);
if (zone.getRawOffset() != zone.getOffset(startOf1900Utc - 1)) {
System.out.println(id);
}
}
}
}
上記のコードは、私のWindowsマシンでは何も出力されません。したがって、1900年の開始時に標準的なオフセット以外のオフセットを持つタイムゾーンは、それを移行としてカウントします。TZDB自体はそれ以前にさかのぼるデータを持っており、標準時の考え方に依存しない(つまり、これは
getRawOffset
は有効な概念であると仮定しているので、他のライブラリはこの人工的な移行を導入する必要はありません。
関連
-
Java エラー報告 スレッド "main" での例外 java.util.NoSuchElementException
-
スタイルシートとして解釈されるリソースが、MIMEタイプtext/htmlで転送される。
-
eclipse アクセス制限です。タイプ 'xxx' は API ではありません(必須ライブラリ '' の制限)。
-
スキャナは、タイプに解決することはできません最もルーキー初心者の質問
-
Javaエラーメッセージがenclosingクラスでない
-
java.lang.NoClassDefFoundError: org.apache.jasper.el.ELContextImpl クラスを初期化できませんでした。
-
SocketTimeoutExceptionの解決方法です。読み込みがタイムアウトした
-
SocketTimeoutExceptionです。読み込みがタイムアウトしました
-
Google Chromeのエラー「Not allowed to load local resource」の解決策について
-
[解決済み】sumの順番を変えると違う結果になるのはなぜですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
スレッド "main "での例外をEclipseで解決 java.lang.Error: 未解決のコンパイル問題、コンパイラとパッケージの不整合
-
エラーが報告されました。リソースの読み込みに失敗しました:サーバーは500(内部サーバーエラー)のステータスで応答しました。
-
this()の呼び出しはコンストラクタ本体の最初の文でなければならない 例外解決と原因分析
-
エラーの解決方法 jarfile XXX.jarにアクセスできません。
-
スレッド "main" での例外 java.lang.ArrayIndexOutOfBoundsException: 1
-
[オリジナル】java学習ノート【II】よくあるエラー クラスパス上のクラスファイルが見つからない、またはアクセスできない場合
-
java -serverコマンドで「Error: no `server' JVM at ... jvm.dll」を解決する方法です。
-
[解決済み] LocalDateTimeで日付をパース/フォーマットする方法は?(Java 8)
-
[解決済み】Javaで時間のないDateを取得する方法は?
-
[解決済み] なぜ配列は共変であり、ジェネリックは不変なのですか?