(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

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは、夫に会ったとき、典型的な交際のアドバイスに逆らいました。

マイケルシーンが非営利の俳優である理由

マイケルシーンが非営利の俳優である理由

マイケルシーンは非営利の俳優ですが、それは正確にはどういう意味ですか?

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

特徴的なスターのコリン・エッグレスフィールドは、RomaDrama Liveでのスリル満点のファンとの出会いについて料理しました!加えて、大会での彼のINSPIREプログラム。

「たどりつけば」をオンラインでストリーミングできない理由

「たどりつけば」をオンラインでストリーミングできない理由

ノーザンエクスポージャーが90年代の最も人気のある番組の1つになった理由を確認するには、Blu-rayまたはDVDプレーヤーをほこりで払う必要があります。

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

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

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

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖は、世界で2番目に大きいボイリング湖です。そこにたどり着くまでのトレッキングは大変で長いですが、努力する価値は十分にあります。

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

サロンからのヘアトリミングや個人的な寄付は、油流出を吸収して環境を保護するのに役立つマットとして再利用できます。

ホワイトハウスの最も記憶に残る結婚式を見てください

ホワイトハウスの最も記憶に残る結婚式を見てください

過去200年以上の間にホワイトハウスで結婚したのはほんの数人です。彼らは誰でしたか、そしてそこで結婚式を獲得するために何が必要ですか?

グッドジョブ、ESPN

グッドジョブ、ESPN

今日のホワイトハウスの記者会見で、報道官のサラ・ハッカビー・サンダースは、スポーツセンターのホストであるイェメル・ヒルのドナルド・トランプに関する最近のツイートについてコメントするよう求められ、大統領と彼の政策を白人至上主義者として説明した。ヒルは彼女のつぶやきのためにESPNによって公に叱責されました。

アマゾンからのこのレミントンツールセールで髪を整える、スタイルを整える、乾かす、または取り除く

アマゾンからのこのレミントンツールセールで髪を整える、スタイルを整える、乾かす、または取り除く

基本的に頭のあらゆる部分から髪の毛を整えたり、ブロードライしたり、まっすぐにしたり、脱毛したりする必要がある場合は、このレミントンゴールドボックスが最適です。今日だけ、Amazonは、すでに人気のあるShortcut Pro Self-HaircutKitやPearlPro Ceramic Flat Ironのように、グルーミングをはるかに簡単にするヘアツールをマークダウンしています。

カナダの元桂冠詩人が、史上最高の文化の盗用でトゥパックとマヤアンジェロウから盗んだ

カナダの元桂冠詩人が、史上最高の文化の盗用でトゥパックとマヤアンジェロウから盗んだ

トゥパックシャクール(ティムモーゼンフェルダー/ゲッティイメージズ); マヤアンジェロウ(マーティンゴッドウィン/ゲッティイメージズ)移動、テイラースウィフト。ケンドールとカイリーは、必要な数の座席を持っています。

テスラは、ハリケーンイルマによる避難を容易にするために、フロリダでの車両の範囲を拡大しています

テスラは、ハリケーンイルマによる避難を容易にするために、フロリダでの車両の範囲を拡大しています

写真:Tesla Motorsフロリダに住んでいて、Tesla Model S、Model X 60、またはModel 60Dを使用している場合、車の自律性は50 km(約30マイル)高くなります。これは失敗ではなく、ハリケーンイルマによる避難作業を容易にするために会社自身が命じた自治権の一時的な延長です。

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya shared a sweet photo in honor of boyfriend Tom Holland's 26th birthday Wednesday

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

シーレン「Ms.JuicyBaby」ピアソンは、先月脳卒中で入院した後、「もう一度たくさんのことをする方法を学ばなければならない」ため、言語療法を受けていることを明らかにしました。

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

オスカー受賞者の世紀半ばの家には、3つのベッドルーム、2つのバス、オーシャンフロントの景色があります。

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、生後4か月の娘、モナコに母乳育児をしていると語った。

投資ノート:Bioscout AU$300万シード

投資ノート:Bioscout AU$300万シード

Bioscoutは、農家を運転席に置くという使命を負っています。Artesian(GrainInnovate)やUniseedと並んで、最新のシードラウンドでチームを支援できることをうれしく思います。問題真菌症による重大な作物の損失は、農民にとって試練であることが証明されています。

リトルマーケットリサーチ1| 2022年のクイックグリンプス遠隔医療市場

リトルマーケットリサーチ1| 2022年のクイックグリンプス遠隔医療市場

遠隔医療は、パンデミック後の時代では新しいものではなく、時代遅れの分野でもありません。しかし、業界を詳しく見ると、需要と供給の強力な持続可能性と、米国で絶え間ない革命となる強力な潜在的成長曲線を示しています。

スタートアップ資金調達環境:タイのスタートアップエコシステムの次は何ですか?

スタートアップ資金調達環境:タイのスタートアップエコシステムの次は何ですか?

2021年は、世界的なベンチャーキャピタル(VC)の資金調達にとって記録的な年でした。DealStreetAsiaによると、東南アジアも例外ではなく、この地域では年間で記録的な25の新しいユニコーンが採掘されました。

ムーアの法則を超えて

ムーアの法則を超えて

計算に対する私たちの欲求とムーアの法則が提供できるものとの間には、指数関数的に増大するギャップがあります。私たちの文明は計算に基づいています—建築と想像力の現在の限界を超える技術を見つけなければなりません。

Language