(1927年に)これらを2回引くと、奇妙な結果が得られるのはなぜですか?

7031
Freewind 2011-07-27 22:15.

次のプログラムを実行すると、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

10 answers

11177
Jon Skeet 2011-07-27 22:31.

上海では12月31日のタイムゾーン変更です。

上海での1927年の詳細については、このページを参照してください。基本的に1927年の終わりの真夜中に、時計は5分52秒戻りました。したがって、「1927-12-31 23:54:08」は実際には2回発生し、Javaは、そのローカルの日付/時刻の可能な後の瞬間としてそれを解析しているように見えます。したがって、違いがあります。

しばしば奇妙で素晴らしいタイムゾーンの世界でのちょうど別のエピソード。

編集:プレスを停止してください!歴史の変化...

TZDBのバージョン2013aで再構築した場合、元の質問はまったく同じ動作を示しなくなります。2013aでは、結果は358秒になり、遷移時間は23:54:08ではなく23:54:03になります。

ユニットテストの形で野田時間にこのような質問を集めているので、私はこれに気づいただけです...テストは現在変更されていますが、それは表示されます-履歴データでさえ安全ではありません。

編集:歴史が再び変わった...

TZDB 2014fでは、変化の時間は、1900年12月31日に移動した、それが今では単なる343秒の変化(間の時間ようだtとはt+1あなたは私が何を意味するか見た場合、344秒です)。

編集: 1900年の移行に関する質問に答えるには、Javaタイムゾーンの実装では、すべてのタイムゾーンが1900UTCの開始前の任意の瞬間の標準時間にあるものとして扱われるようです。

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有効な概念であると想定される)の概念に依存しないため、他のライブラリはこの人為的な移行を導入する必要はありません。

1644
Michael Borgwardt 2011-07-27 22:38.

現地時間の不連続性に遭遇しました:

現地標準時が日曜日に到達しようとしたとき、1928年1月1日00:00:00時計が0:05:52時間から31日土曜日に戻されました。1927年12月23:54:08現地標準時ではなく

これは特に奇妙なことではなく、政治的または行政的な行動によってタイムゾーンが切り替えられたり変更されたりしたため、どこでも一度に発生しました。

688
Raedwald 2011-07-29 01:50.

この奇妙さの教訓は次のとおりです。

  • 可能な限り、UTCで日付と時刻を使用してください。
  • UTCで日付または時刻を表示できない場合は、常にタイムゾーンを指定してください。
  • UTCでの入力日時を要求できない場合は、明示的に指定されたタイムゾーンを要求してください。
379
PatrickO 2011-07-31 06:55.

時間をインクリメントするときは、UTCに変換してから、加算または減算する必要があります。現地時間を表示のみに使用してください。

このようにして、時間または分が2回発生する任意の期間を歩くことができます。

UTCに変換した場合は、1秒ごとに加算し、現地時間に変換して表示します。あなたは11時54分08秒午後通過するでしょうLMT -午後11:59:59 LMT、その後、11時54分08秒午後CST -午後11:59:59 CST。

320
Rajshri 2012-05-16 19:31.

各日付を変換する代わりに、次のコードを使用できます。

long difference = (sDt4.getTime() - sDt3.getTime()) / 1000;
System.out.println(difference);

そして、結果が次のようになることを確認します。

1
236
user1050755 2014-02-18 12:44.

申し訳ありませんが、時間の不連続性が少し移動しました

JDK 6 2年前、及びでJDK 7つい最近で更新25。

学ぶべき教訓:おそらく表示を除いて、UTC以外の時間は絶対に避けてください。

208
Daniel C. Sobral 2014-01-04 04:43.

他の人が説明しているように、そこには時間の不連続性があります。1927-12-31 23:54:08atAsia/Shanghaiには2つのタイムゾーンオフセットがありますが、1927-12-31 23:54:07。には1つのオフセットしかありません。したがって、使用するオフセットに応じて、1秒の違い、または5分53秒の違いがあります。

このオフセットのわずかなシフトは、私たちが慣れている通常の1時間の夏時間(夏時間)の代わりに、問題を少し覆い隠します。

2013aのタイムゾーンデータベースの更新により、この不連続性が数秒前に移動しましたが、その影響は引き続き観察可能であることに注意してください。

java.timeJava 8の新しいパッケージを使用すると、これをより明確に確認し、それを処理するためのツールを提供できます。与えられた:

DateTimeFormatterBuilder dtfb = new DateTimeFormatterBuilder();
dtfb.append(DateTimeFormatter.ISO_LOCAL_DATE);
dtfb.appendLiteral(' ');
dtfb.append(DateTimeFormatter.ISO_LOCAL_TIME);
DateTimeFormatter dtf = dtfb.toFormatter();
ZoneId shanghai = ZoneId.of("Asia/Shanghai");

String str3 = "1927-12-31 23:54:07";  
String str4 = "1927-12-31 23:54:08";  

ZonedDateTime zdt3 = LocalDateTime.parse(str3, dtf).atZone(shanghai);
ZonedDateTime zdt4 = LocalDateTime.parse(str4, dtf).atZone(shanghai);

Duration durationAtEarlierOffset = Duration.between(zdt3.withEarlierOffsetAtOverlap(), zdt4.withEarlierOffsetAtOverlap());

Duration durationAtLaterOffset = Duration.between(zdt3.withLaterOffsetAtOverlap(), zdt4.withLaterOffsetAtOverlap());

その後durationAtEarlierOffset、1秒にdurationAtLaterOffsetなり、5分53秒になります。

また、これら2つのオフセットは同じです。

// Both have offsets +08:05:52
ZoneOffset zo3Earlier = zdt3.withEarlierOffsetAtOverlap().getOffset();
ZoneOffset zo3Later = zdt3.withLaterOffsetAtOverlap().getOffset();

しかし、これら2つは異なります。

// +08:05:52
ZoneOffset zo4Earlier = zdt4.withEarlierOffsetAtOverlap().getOffset();

// +08:00
ZoneOffset zo4Later = zdt4.withLaterOffsetAtOverlap().getOffset();

と比較1927-12-31 23:59:59しても同じ問題が見られますが1928-01-01 00:00:00、この場合、より長い発散を生み出すのは以前のオフセットであり、2つの可能なオフセットがあるのは以前の日付です。

これにアプローチする別の方法は、移行が進行中であるかどうかを確認することです。これは次のように実行できます。

// Null
ZoneOffsetTransition zot3 = shanghai.getRules().getTransition(ld3.toLocalDateTime);

// An overlap transition
ZoneOffsetTransition zot4 = shanghai.getRules().getTransition(ld3.toLocalDateTime);

isOverlap()andisGap()メソッドを使用して、遷移が、その日付/時刻に複数の有効なオフセットがあるオーバーラップであるか、その日付/時刻がそのゾーンIDで無効であるギャップであるかを確認できzot4ます。

これが、Java 8が広く利用可能になった後、またはJSR310バックポートを採用するJava7を使用している人々にとって、この種の問題を処理するのに役立つことを願っています。

173
user1050755 2014-11-27 05:58.

IMHOJavaでの広範囲にわたる暗黙のローカリゼーションは、その単一の最大の設計上の欠陥です。これはユーザーインターフェイスを対象としている場合がありますが、率直に言って、プログラマーが正確にターゲットオーディエンスではないため、基本的にローカリゼーションを無視できる一部のIDEを除いて、今日のユーザーインターフェイスにJavaを実際に使用しています。(特にLinuxサーバーで)次の方法で修正できます。

  • 書き出す LC_ALL=C TZ=UTC
  • システムクロックをUTCに設定します
  • どうしても必要な場合を除いて、ローカライズされた実装を使用しないでください(つまり、表示のみ)

Javaコミュニティプロセスのメンバー私がお勧めします。

  • ローカライズされたメソッドをデフォルトではなく作成しますが、ユーザーはローカリゼーションを明示的に要求する必要があります。
  • 代わりにFIXEDデフォルトUTF-8/UTCとして使用してください。これは、今日の単なるデフォルトだからです。このようなスレッドを作成する場合を除いて、他のことをする理由はありません。

つまり、グローバル静的変数は反OOパターンではないのですか?いくつかの基本的な環境変数によって与えられるこれらの一般的なデフォルトは他にありません.......

25
zixuan 2019-02-11 11:47.

他の人が言ったように、それは上海での1927年の時間の変化です。

それはだった23:54:07現地標準時間で、上海では、しかし、その後、5分52秒後に、それは、次の日になって00:00:00、その後、現地標準時間がに戻します23:54:08。そのため、2つの時間の差は、予想どおり1秒ではなく343秒になります。

米国のような他の場所でも時間が混乱する可能性があります。米国には夏時間があります。夏時間が始まると、時間が1時間進みます。しかし、しばらくすると、夏時間が終了し、標準のタイムゾーンに1時間戻ります。そのため、米国で時間を比較すると、違いは36001秒ではなく約秒になることがあります。

しかし、これらの2回の変更には何か違いがあります。後者は絶えず変化し、前者は単なる変化でした。同じ量だけ元に戻ったり、再び変化したりすることはありませんでした。

表示のようにUTC以外の時間を使用する必要がある場合を除いて、UTCを使用することをお勧めします。

5
Neeraj Bansal 2020-07-07 04:10.

これは、1927年12月31日の上海でのタイムゾーンルールであるために発生します。このページに移動して「1900年から1924年のタイムゾーンの変更」を選択すると、1900年の日付と時刻が「すべての期間のUTC + 8:05:43時間」であることがわかります。

したがって、Javaは、その年のそのタイムゾーンに設定された時刻を表示しているだけです。

デフォルトのタイムゾーンを香港に変更すると、正しい結果が表示されます。

TimeZone.setDefault(TimeZone.getTimeZone("Asia/Hong_Kong"));

タイムゾーンがCST(中国標準時、アジア/上海の「3文字相当」)からHKT(香港のタイムゾーンの3文字の名前)に変更されたことに注意してください。

しかし、タイムゾーンを変更することは良い解決策ではありません。したがって、代わりに、可能な限りシステムUTC時間を使用してください。変換後は常に現地時間を示します。

Related questions

MORE COOL STUFF

「水曜日」シーズン1の中心には大きなミステリーがあります

「水曜日」シーズン1の中心には大きなミステリーがあります

Netflixの「水曜日」は、典型的な10代のドラマ以上のものであり、実際、シーズン1にはその中心に大きなミステリーがあります.

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ケイト・ミドルトンは、州の夕食会と州の訪問中にカミラ・パーカー・ボウルズからスポットライトを奪いたくなかった、と専門家は言う.

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンが、オリビア・ワイルドが彼女とハリー・スタイルズとの間の「難しい」が「非常に友好的」な分割を恒久的にすることを望んでいる理由を見つけてください.

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする 

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする 

エリザベス女王の死後、ケイト・ミドルトンが舞台裏で「非常に困難な時期」を過ごしていたと伝えられている理由を調べてください.

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セント ヘレナ島のジェイコブズ ラダーは 699 段の真っ直ぐ上る階段で、頂上に到達すると証明書が発行されるほどの難易度です。

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

Total War:Warhammer:Kotakuレビュー

Total War:Warhammer:Kotakuレビュー

私はこのゲームを嫌う準備ができていました。先週の前に、Total War:Warhammerについての私の考えがありました:それでもここに私は、私の手にある完成品であり、私は変わった男です。

涙の道:軍事化された帝国主義勢力がスタンディングロックキャンプを占領

涙の道:軍事化された帝国主義勢力がスタンディングロックキャンプを占領

スタンディングロックスー族のメンバーと水の保護者は、ノースダコタ州のスタンディングロックにあるオセティサコウィンキャンプを去ります。(Twitter経由のCNNスクリーンショット)火と煙がスカイラインを覆い、スタンディングロックスー族のメンバーと水の保護者が、聖なるものを守りながら建てた家、オセティサコウィン(セブンカウンシルファイアーズ)キャンプから行進し、太鼓を打ち、歌い、祈りました。ダコタアクセスパイプラインとしても知られる「ブラックスネーク」からの土地。

シアーズとKマートはイヴァンカ・トランプの商品を自分たちで取り除いています

シアーズとKマートはイヴァンカ・トランプの商品を自分たちで取り除いています

写真:APシアーズとKマートは、イヴァンカ・トランプのトランプホームアイテムのコレクションも、誰も購入したくないために削除しました。シアーズとKマートの両方の親会社であるシアーズホールディングスは、土曜日のABCニュースへの声明で、彼らが気にかけていると辛抱強く説明しましたトランプラインを売り続けるにはお金を稼ぐことについてあまりにも多く。

ポテトチップスでたった10分でスペインのトルティーヤを作る

ポテトチップスでたった10分でスペインのトルティーヤを作る

伝統的なスペインのトルティーヤは通常、オリーブオイルで柔らかくなるまで調理されたポテトから始まります(30分以上かかる場合があります)が、ケトルで調理されたポテトチップスの助けを借りてわずか10分でテーブルに置くことができます。上のビデオはすべてがバラバラにならないように裏返す方法を含め、レシピ全体を説明しますが、必要なのは4〜5個の卵と3カップのケトルチップスだけです。

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、子供向けのパズルの本の序文を書き、ジョージ王子、シャーロット王女、ルイ王子と一緒にテキストを読むと述べた.

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

Yak's Produce は、数十個のつぶれたメロンを野生動物のリハビリ専門家であるレスリー グリーンと彼女のルイジアナ州の救助施設で暮らす 42 匹の動物に寄付しました。

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

8 枚目のスタジオ アルバムのリリースに向けて準備を進めているデミ ロヴァートは、「スーパー グレート ガイ」と付き合っている、と情報筋は PEOPLE に確認しています。

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

イーサン プラスの誕生日のお祝いは、TLC のウェルカム トゥ プラスビルのシーズン 4 のフィナーレで、戦争中の母親のキム プラスと妻のオリビア プラスを結びつけました。

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

ホームオフィスのセットアップ術を極めよう!AppExert の開発者は、家族全員が一緒にいる場合でも、在宅勤務の技術を習得しています。祖父や曽祖父が共同家族で暮らしていた頃の記憶がよみがえりました。

2022 年、私たちのデジタル ライフはどこで終わり、「リアル ライフ」はどこから始まるのでしょうか?

20 年前のタイムトラベラーでさえ、日常生活におけるデジタルおよびインターネットベースのサービスの重要性に驚くことでしょう。MySpace、eBay、Napster などのプラットフォームは、高速化に焦点を合わせた世界がどのようなものになるかを示してくれました。

ニューロマーケティングの秘密科学

ニューロマーケティングの秘密科学

マーケティング担当者が人間の欲望を操作するために使用する、最先端の (気味が悪いと言う人もいます) メソッドを探ります。カートをいっぱいにして 3 桁の領収書を持って店を出る前に、ほんの数点の商品を買いに行ったことはありませんか? あなたは一人じゃない。

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

私たちが住んでいる世界を確実に理解するには、データが必要です。ただし、空間参照がない場合、このデータは地理的コンテキストがないと役に立たなくなる可能性があります。

Language