1. 序章

このチュートリアルでは、 Java 8 Date / TimeAPIを使用して日付を比較する方法に焦点を当てます。 2つの日付が等しいかどうかを確認するためのさまざまな方法と、日付を比較する方法について詳しく説明します。

2. 日付の比較

Javaで日付を表現する基本的な方法は、LocalDateです。 2019年8月10日と2019年7月1日を表す2つのLocalDateオブジェクトインスタンスについて考えてみましょう。

LocalDate firstDate = LocalDate.of(2019, 8, 10);
LocalDate secondDate = LocalDate.of(2019, 7, 1);

isAfter()、isBefore()、isEqual()メソッド、およびequals()とcompareTo()を使用して、2つのLocalDateオブジェクトを比較します。

isAfter()メソッドを使用して、日付インスタンスが他の指定された日付より後かどうかを確認します。 したがって、次のJUnitアサーションは次のように渡されます。

assertThat(firstDate.isAfter(secondDate), is(true));

同様に、メソッド isBefore()は、日付インスタンスが他の指定された日付より前であるかどうかをチェックします。

assertThat(firstDate.isBefore(secondDate), is(false));

メソッドisEqual()は、日付がローカルタイムライン上の他の指定された日付と同じポイントを表すかどうかをチェックします。

assertThat(firstDate.isEqual(firstDate), is(true));
assertThat(firstDate.isEqual(secondDate), is(false));

2.1. Compareableインターフェースを使用した日付の比較

equals()メソッドは、 isEqual()と同じ結果を返しますが、渡された引数が同じタイプ(この場合は LocalDate )である場合に限ります。 )::

assertThat(firstDate.equals(secondDate), is(false));

代わりに、 isEqual()メソッドを使用して、 JapaneseDate ThaiBuddhistDateなどの異なるタイプのオブジェクトと比較できます。

Compareable インターフェイスで定義されているように、 compareTo()メソッドを使用して、2つの日付インスタンスを比較できます。

assertThat(firstDate.compareTo(secondDate), is(1));
assertThat(secondDate.compareTo(firstDate), is(-1));

3. 時間コンポーネントを含む日付インスタンスの比較

このセクションでは、2つのLocalDateTimeインスタンスを比較する方法について説明します。 LocalDateTime インスタンスには、日付と時刻のコンポーネントが含まれています。

LocalDateと同様に、2つのLocalDateTimeインスタンスをメソッドisAfter()、isBefore()、およびisEqual()と比較しています。 さらに、 equals()および compareTo()は、LocalDate。で説明したのと同様の方法で使用できます。

同様に、2つのZonedDateTimeインスタンスを比較するために同じメソッドを使用できます。 同じ日のニューヨークの現地時間8:00とベルリンの現地時間14:00を比較してみましょう。

ZonedDateTime timeInNewYork = 
  ZonedDateTime.of(2019, 8, 10, 8, 0, 0, 0, ZoneId.of("America/New_York"));
ZonedDateTime timeInBerlin = 
  ZonedDateTime.of(2019, 8, 10, 14, 0, 0, 0, ZoneId.of("Europe/Berlin"));

assertThat(timeInNewYork.isAfter(timeInBerlin), is(false));
assertThat(timeInNewYork.isBefore(timeInBerlin), is(false));
assertThat(timeInNewYork.isEqual(timeInBerlin), is(true));

両方のZonedDateTimeインスタンスは同じ瞬間を表しますが、等しいJavaオブジェクトを表すわけではありません。 内部的には、LocalDateTimeフィールドとZoneIdフィールドが異なります。

assertThat(timeInNewYork.equals(timeInBerlin), is(false)); 
assertThat(timeInNewYork.compareTo(timeInBerlin), is(-1));

4. 追加の比較

少し複雑な比較のために、単純なユーティリティクラスを作成しましょう。

まず、LocalDateTimeLocalDateのインスタンスが同じ日にあるかどうかを確認します。

public static boolean isSameDay(LocalDateTime timestamp, 
  LocalDate localDateToCompare) {
    return timestamp.toLocalDate().isEqual(localDateToCompare);
}

次に、LocalDateTimeの2つのインスタンスが同じ日にあるかどうかを確認します。

public static boolean isSameDay(LocalDateTime timestamp, 
  LocalDateTime timestampToCompare) {
    return timestamp.truncatedTo(DAYS)
      .isEqual(timestampToCompare.truncatedTo(DAYS));
}

trunkedTo(TemporalUnit)メソッドは、指定されたレベルで日付を切り捨てます。この例では、日付です。

第三に、1時間のレベルで比較を実装できます。

public static boolean isSameHour(LocalDateTime timestamp, 
  LocalDateTime timestampToCompare) {
    return timestamp.truncatedTo(HOURS)
      .isEqual(timestampToCompare.truncatedTo(HOURS));
}

最後に、同様の方法で、2つのZonedDateTimeインスタンスが同じ時間内に発生するかどうかを確認できます。

public static boolean isSameHour(ZonedDateTime zonedTimestamp, 
  ZonedDateTime zonedTimestampToCompare) {
    return zonedTimestamp.truncatedTo(HOURS)
      .isEqual(zonedTimestampToCompare.truncatedTo(HOURS));
}

2つのZonedDateTimeオブジェクトは、現地時間が異なっていても(それぞれ、8:30と14:00)、実際には同じ時間内に発生していることがわかります。

ZonedDateTime zonedTimestamp = 
  ZonedDateTime.of(2019, 8, 10, 8, 30, 0, 0, ZoneId.of("America/New_York"));
ZonedDateTime zonedTimestampToCompare = 
  ZonedDateTime.of(2019, 8, 10, 14, 0, 0, 0, ZoneId.of("Europe/Berlin"));

assertThat(DateTimeComparisonUtils.
  isSameHour(zonedTimestamp, zonedTimestampToCompare), is(true));

5. Old JavaDateAPIでの比較

Java 8より前は、日付/時刻情報を操作するためにjava.util.Dateおよびjava.util.Calendarクラスを使用する必要がありました。 古いJavaDateAPIの設計には、複雑でスレッドセーフではないなど、多くの欠陥があります。 java.util.Date インスタンスは、実際の日付ではなく、「インスタントインタイム」を表します。

解決策の1つは、 JodaTimeライブラリを使用することでした。 Java 8のリリース以降、 Java 8 Date / TimeAPIに移行することをお勧めします。

LocalDateおよびLocalDateTimeと同様に、java.util.Dateオブジェクトとjava.util.Calendarオブジェクトの両方に、2つの日付インスタンスを比較するためのafter()、before()、compareTo()、およびequals()メソッドがあります。 日付は、ミリ秒のレベルで、時間の瞬間として比較されます。

Date firstDate = toDate(LocalDateTime.of(2019, 8, 10, 0, 00, 00));
Date secondDate = toDate(LocalDateTime.of(2019, 8, 15, 0, 00, 00));

assertThat(firstDate.after(secondDate), is(false));
assertThat(firstDate.before(secondDate), is(true));
assertThat(firstDate.compareTo(secondDate), is(-1));
assertThat(firstDate.equals(secondDate), is(false));

より複雑な比較には、 Apache CommonsLangライブラリのDateUtilsを使用できます。 このクラスには、DateおよびCalendarオブジェクトを処理するための多くの便利なメソッドが含まれています。

public static boolean isSameDay(Date date, Date dateToCompare) {
    return DateUtils.isSameDay(date, dateToCompare);
}

public static boolean isSameHour(Date date, Date dateToCompare) {
    return DateUtils.truncatedEquals(date, dateToCompare, Calendar.HOUR);
}

さまざまなAPIから発生した日付オブジェクトを比較するには、最初に適切な変換を行ってから、比較を適用する必要があります。詳細については、日付をLocalDateまたはLocalDateTimeに変換してから戻るを参照してください。 ]チュートリアル。

6. 結論

この記事では、Javaで日付インスタンスを比較するさまざまな方法について説明しました。

Java 8 Date / Timeクラスには、時間帯の有無にかかわらず、日付を比較するための豊富なAPIがあります。 また、日、時、分などの粒度で日付を比較する方法も確認しました。

追加の例を含め、この記事で言及されているすべてのコードスニペットは、GitHubから入手できます。