java.time比較は一貫していません

Matanイツァーク:

私が使用しているLocalData私のコード内のオブジェクトを、そして私が使用していることに気づいたcompareTo方法が一貫していません。
私が使用してcompareTo2つの日付の間(日中)の差異を得るために方法を。
それだけで同じか月間の日付のために働くようにしかし、それはそうです。

私はこの問題を示すために、コードスニペットを添付しています:

import java.text.MessageFormat;
import java.time.LocalDate;

public class timeComparison {
    public static void main(String[] args) {
        LocalDate valentinesDay = LocalDate.of(2020, 2, 14);
        LocalDate darwinDay = LocalDate.of(2020, 2, 12);
        LocalDate leapDay = LocalDate.of(2020, 2, 29);
        LocalDate superTuesday = LocalDate.of(2020, 3, 3);

        String valentinesVsDarwin = MessageFormat.format(
                "Valentine day is {0} days after Darwin day",
                valentinesDay.compareTo(darwinDay)
        );
        System.out.println(valentinesVsDarwin);

        String darwinVsLeap = MessageFormat.format(
                "Leap day is {0} days after Darwin day",
                leapDay.compareTo(darwinDay)
        );
        System.out.println(darwinVsLeap);

        String superTuesdayVsLeap = MessageFormat.format(
                "Super Tuesday is {0} days after leap day",
                superTuesday.compareTo(leapDay)
        );
        System.out.println(superTuesdayVsLeap);
    }
}

私が手出力は次のようになります。

Valentine day is 2 days after Darwin day
Leap day is 17 days after Darwin day
Super Tuesday is 1 days after leap day

私が取得するために期待していましたSuper Tuesday is 3 days after leap day

私は、問題の原因とどのように私は2つの別々の日付の差を得ることができるかを知りたいと思います。

Matanイツァーク:

TL; DR

compareToこの方法は、この使用のためのものではありません。
時間差を示さない、オーダーの指標であることを意味します。

謎を解きます

これより良いものを理解するためにソースコードを見ることができますLocalDate
任意のIDE上では、ソースコードを表示するには、「[移動=>実装」を選択することができます。

public int compareTo(ChronoLocalDate other) {
    return other instanceof LocalDate ? this.compareTo0((LocalDate)other) : super.compareTo(other);
}

int compareTo0(LocalDate otherDate) {
    int cmp = this.year - otherDate.year;
    if (cmp == 0) {
        cmp = this.month - otherDate.month;
        if (cmp == 0) {
            cmp = this.day - otherDate.day;
        }
    }

    return cmp;
}

上記のソースコードから、あなたはそれを学ぶことができるcompareTo方法はありません(それは、数年かもしれヶ月かもしれない、またはかもしれない日の日付の間の差ではなく、違いがあり、最初のパラメータでの日付の差を返します日々)。

目的は何ですかcompareToメソッド

上記のコードとその目的を理解するために、
1は、Javaでの比較がどのように動作するかを少し理解する必要があります。
JavaのLocalDateクラスが実装ChronoLocalDate同等のオブジェクトです。
これは、このオブジェクトが別のオブジェクトとそれ自体を比較することが可能であることを意味します。
そうするためには、クラス自体は実装する必要がありjava.lang.Comparable、そのインスタンスを比較するためのインターフェイスを。
で説明したようにJavaのAPIドキュメント

このインタフェースは、実装する各クラスのオブジェクトに全体順序付けを課します。この順序は、クラスの自然順序付けと呼ばれ、クラスのcompareToメソッドは、その自然の比較方法と呼ばれています。

また、方法の詳細compareTo方法は以下の通りであります:

比較順に指定したオブジェクトとこのオブジェクトを。
戻り負の整数、ゼロ、またはこのオブジェクトが等しいか、または指定されたオブジェクトよりも大きい、未満であるように、正の整数。

仕事との比較のためのために、我々は、与党上記に対応していること整数を返す必要があること、を意味しています。そのため、番号自体ではなく、オブジェクトの「注文」の指標であるよりも、何の意味もありません。最初の数年間で、その後数ヶ月で、そして日で終了中:方法は、上記のように、日中の差を計算ではなく、オブジェクトの自然な順序のための即時の表示を求めていない理由です。
あなたが別のマウント持っていた日数を比較したところ-この方法は、まさにそれを示しました。
あなたは2020年に日と2018年の日付の間で比較した場合も、同様とするだろう-あなたが2になるだろう/ -2結果として。

あなたは、データの差を測定する方法

私たちは、その見つけたcompareTo日付の差の測定ツールとして使用されるものではありません。
あなたはどちらかを使用することができますPeriodChronoUnit、あなたのニーズに応じて、。
Javaのからの期間と期間のチュートリアル

ChronoUnit

ChronoUnitザ時間的パッケージで論じ列挙は、時間を測定するために使用される単位を定義します。あなたは、このような日や秒など、時間のみの単一単位の時間の量を測定したいときに有効です。方法の間のすべての時間ベースのオブジェクトで動作し、それは、単一の単位の量を返します。
ChronoUnit.between

限目

日付ベースの値(年、月、日)との時間の量を定義するには、使用Periodするクラスを。このクラスは、次のようなさまざまなgetメソッドを、提供あなたが期間からの時間の量を抽出することができるように、。年、月、日:時間の合計時間は、一緒にすべての3つのユニットで表現されます。な日など、時間の単一単位で測定された時間の量を提示するには、使用することができます方法を。
PeriodgetMonthsgetDaysgetYears

ChronoUnit.between

ここでは方法上記の使用方法を示すコードスニペットです:

jshell> import java.time.LocalDate;

jshell> LocalDate darwinDay = LocalDate.of(2020, 2, 12);
darwinDay ==> 2020-02-12

jshell> LocalDate leapDay = LocalDate.of(2020, 2, 29);
leapDay ==> 2020-02-29

jshell> leapDay.compareTo(darwinDay);
 ==> 17

jshell> import java.time.Period;

jshell> Period.between(darwinDay, leapDay).getDays();
 ==> 17

jshell> import java.time.temporal.ChronoUnit;

jshell> ChronoUnit.DAYS.between(darwinDay, leapDay);
 ==> 17

jshell> LocalDate now = LocalDate.of(2020, 3, 28);
now ==> 2020-03-28

jshell> LocalDate yearAgo = LocalDate.of(2019, 3, 28);
yearAgo ==> 2019-03-28

jshell> yearAgo.compareTo(now);
 ==> -1

jshell> Period.between(yearAgo, now).getDays();
 ==> 0

jshell> ChronoUnit.DAYS.between(yearAgo, now);
 ==> 366

おすすめ

転載: http://10.200.1.11:23101/article/api/json?id=387308&siteId=1