1. 概要

このクイックチュートリアルでは、2つのjava.util.Dateオブジェクトが同じ日であるかどうかを確認するいくつかの異なる方法について学習します。

まず、コアJava、つまりJava 8の機能を使用したソリューションを検討してから、Java8より前の2つの代替案を検討します。

最後に、いくつかの外部ライブラリ( Apache Commons Lang、Joda-Time、およびDate4J )についても見ていきます。

2. コアJava

クラスDateは、ミリ秒の精度で特定の瞬間を表します。 2つのDateオブジェクトに同じ日が含まれているかどうかを確認するには、両方のオブジェクトでYear-Month-Dayが同じかどうかを確認し、時間アスペクトを破棄する必要があります。

2.1. LocalDateを使用する

Java8の新しいDate-TimeAPIでは、LocalDateオブジェクトを使用できます。 これは、時刻のない日付を表す不変オブジェクトです。

このクラスを使用して、2つのDateオブジェクトが同じ日であるかどうかを確認する方法を見てみましょう。

public static boolean isSameDay(Date date1, Date date2) {
    LocalDate localDate1 = date1.toInstant()
      .atZone(ZoneId.systemDefault())
      .toLocalDate();
    LocalDate localDate2 = date2.toInstant()
      .atZone(ZoneId.systemDefault())
      .toLocalDate();
    return localDate1.isEqual(localDate2);
}

この例では、デフォルトのタイムゾーンを使用して両方のDateオブジェクトをLocalDateに変換しました。 変換したら、isEqualメソッドを使用してLocalDateオブジェクトが等しいかどうかをチェックする必要があります。

したがって、このアプローチを使用すると、2つのDateオブジェクトに同じ日が含まれているかどうかを判断できます。

2.2. インスタントを使用する

上記の例では、DateオブジェクトをLocalDateオブジェクトに変換するときに、中間オブジェクトとしてInstantを使用しました。 Java 8で導入されたインスタントは、特定の時点を表します

Instantオブジェクトを直接DAYSユニットに切り捨てることができます。これにより、時間フィールドの値がゼロに設定され、それらを比較できます。

public static boolean isSameDayUsingInstant(Date date1, Date date2) {
    Instant instant1 = date1.toInstant()
      .truncatedTo(ChronoUnit.DAYS);
    Instant instant2 = date2.toInstant()
      .truncatedTo(ChronoUnit.DAYS);
    return instant1.equals(instant2);
}

2.3. SimpleDateFormatを使用する

Javaの初期バージョン以降、 SimpleDateFormat クラスを使用して、DateStringオブジェクト表現を変換することができました。 このクラスには、多くのパターンを使用した変換がサポートされています。 この場合、パターン「yyyyMMdd」を使用します。

これを使用して、 Dateをフォーマットし、 String オブジェクトに変換してから、標準のequalsメソッドを使用して比較します。

public static boolean isSameDay(Date date1, Date date2) {
    SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
    return fmt.format(date1).equals(fmt.format(date2));
}

2.4. カレンダーを使用する

Calendar クラスは、特定の瞬間のさまざまな日時単位の値を取得するためのメソッドを提供します。

まず、 Calendar インスタンスを作成し、指定された各日付を使用してCalendarオブジェクトの時刻を設定する必要があります。 次に、クエリを実行して Year-Month-Day属性を個別に比較して、Dateオブジェクトが同じ日であるかどうかを判断できます。

public static boolean isSameDay(Date date1, Date date2) {
    Calendar calendar1 = Calendar.getInstance();
    calendar1.setTime(date1);
    Calendar calendar2 = Calendar.getInstance();
    calendar2.setTime(date2);
    return calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR)
      && calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH)
      && calendar1.get(Calendar.DAY_OF_MONTH) == calendar2.get(Calendar.DAY_OF_MONTH);
}

3. 外部ライブラリ

コアJavaによって提供される新旧のAPIを使用してDateオブジェクトを比較する方法を十分に理解したので、いくつかの外部ライブラリを見てみましょう。

3.1. Apache Commons Lang DateUtils

DateUtilsクラスは、従来のCalendarオブジェクトとDateオブジェクトの操作を容易にする多くの便利なユーティリティを提供します

Apache Commons Lang アーティファクトは、 MavenCentralから入手できます。

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>

次に、DateUtilsのメソッドisSameDayを使用できます。

DateUtils.isSameDay(date1, date2);

3.2. 城田タイムライブラリー

コアJavaDateおよびTimeライブラリの代替はJoda-Timeです。 この広く使用されているライブラリは、日付と時刻を操作するときに優れた代替手段として機能します。

アーティファクトはMavenCentralにあります。

<dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
    <version>2.10</version>
</dependency>

このライブラリでは、org.joda.time.LocalDateは時間のない日付を表します。 したがって、java.util.DateオブジェクトからLocalDateオブジェクトを作成し、それらを比較できます。

public static boolean isSameDay(Date date1, Date date2) {
    org.joda.time.LocalDate localDate1 = new org.joda.time.LocalDate(date1);
    org.joda.time.LocalDate localDate2 = new org.joda.time.LocalDate(date2);
    return localDate1.equals(localDate2);
}

3.3. Date4Jライブラリ

Date4j は、使用できる単純で単純な実装も提供します。

同様に、 MavenCentralからも入手できます。

<dependency>
    <groupId>com.darwinsys</groupId>
    <artifactId>hirondelle-date4j</artifactId>
    <version>1.5.1</version>
</dependency>

このライブラリを使用して、java.util.DateオブジェクトからDateTimeオブジェクトを構築する必要があります。 次に、単純にisSameDayAsメソッドを使用できます。

public static boolean isSameDay(Date date1, Date date2) {
    DateTime dateObject1 = DateTime.forInstant(date1.getTime(), TimeZone.getDefault());
    DateTime dateObject2 = DateTime.forInstant(date2.getTime(), TimeZone.getDefault());
    return dateObject1.isSameDayAs(dateObject2);
}

4. 結論

このクイックチュートリアルでは、2つの java.util.Dateオブジェクトに同じ日が含まれているかどうかを確認するいくつかの方法について説明しました。

いつものように、記事の完全なソースコードは、GitHubから入手できます。