Javaにおける2つの日付の違い

Javaの2つの日付の違い

1. 概要

この簡単な記事では、Javaで2つの日付の差を計算する複数の可能性について説明します。

参考文献:

Javaでの増分日

日付に日付を追加するためのさまざまなコアおよびサードパーティの方法の概要

Javaで文字列が有効な日付かどうかを確認する

Javaで文字列が有効な日付であるかどうかを確認するさまざまな方法を見てください。

2. コアJava

2.1. java.util.Dateを使用して日数の違いを見つける

まず、コアJava APIを使用して計算を行い、2つの日付の間の日数を決定します。

@Test
public void givenTwoDatesBeforeJava8_whenDifferentiating_thenWeGetSix()
  throws ParseException {

    SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy", Locale.ENGLISH);
    Date firstDate = sdf.parse("06/24/2017");
    Date secondDate = sdf.parse("06/30/2017");

    long diffInMillies = Math.abs(secondDate.getTime() - firstDate.getTime());
    long diff = TimeUnit.DAYS.convert(diffInMillies, TimeUnit.MILLISECONDS);

    assertEquals(diff, 6);
}

2.2. java.timeの使用– Java8以降

PeriodDuration:を組み合わせて、2つの日付(時間の有無にかかわらず)を表すためにLocalDate, LocalDateTimeを使用すると、差の計算がより直感的になります。

LocalDateの違い:

@Test
public void givenTwoDatesInJava8_whenDifferentiating_thenWeGetSix() {
    LocalDate now = LocalDate.now();
    LocalDate sixDaysBehind = now.minusDays(6);

    Period period = Period.between(now, sixDaysBehind);
    int diff = period.getDays();

    assertEquals(diff, 6);
}

LocalDateTimeの場合:

@Test
public void givenTwoDateTimesInJava8_whenDifferentiating_thenWeGetSix() {
    LocalDateTime now = LocalDateTime.now();
    LocalDateTime sixMinutesBehind = now.minusMinutes(6);

    Duration duration = Duration.between(now, sixMinutesBehind);
    long diff = Math.abs(duration.toMinutes());

    assertEquals(diff, 6);
}

Hereは、このAPIについてもう少し詳しく説明しています。

2.3. java.time.temporal.ChronoUnitを使用して秒単位の違いを見つける

Java 8のTime APIは、日時の単位を表します。 TemporalUnit interfaceを使用した秒または日。 Each unit provides an implementation for a method named between to calculate the amount of time between two temporal objects in terms of that specific unit

たとえば、2つのLocalDateTimes間の秒数を計算するには、次のようにします。

@Test
public void givenTwoDateTimesInJava8_whenDifferentiatingInSeconds_thenWeGetTen() {
    LocalDateTime now = LocalDateTime.now();
    LocalDateTime tenSecondsLater = now.plusSeconds(10);

    long diff = ChronoUnit.SECONDS.between(now, tenSecondsLater);

    assertEquals(diff, 10);
}

ChronoUnitは、TemporalUnitインターフェイスを実装することにより、具体的な時間単位のセットを提供します。 It’s highly recommended to static import the ChronoUnit enum values to achieve more readability:

import static java.time.temporal.ChronoUnit.SECONDS;

// omitted
long diff = SECONDS.between(now, tenSecondsLater);

また、ZonedDateTime.であっても、互換性のある2つの時間オブジェクトをbetween メソッドに渡すことができます。

ZonedDateTimeの優れている点は、異なるタイムゾーンに設定されている場合でも計算が機能することです。

@Test
public void givenTwoZonedDateTimesInJava8_whenDifferentiating_thenWeGetSix() {
    LocalDateTime ldt = LocalDateTime.now();
    ZonedDateTime now = ldt.atZone(ZoneId.of("America/Montreal"));
    ZonedDateTime sixMinutesBehind = now
      .withZoneSameInstant(ZoneId.of("Asia/Singapore"))
      .minusMinutes(6);

    long diff = ChronoUnit.MINUTES.between(sixMinutesBehind, now);

    assertEquals(diff, 6);
}

2.4. java.time.temporal.Temporalの使用until()

Temporalオブジェクト(例: LocalDate or ZonedDateTime, provides an until method to calculate the amount of time until another temporal in terms of the specified unit:

@Test
public void givenTwoDateTimesInJava8_whenDifferentiatingInSecondsUsingUntil_thenWeGetTen() {
    LocalDateTime now = LocalDateTime.now();
    LocalDateTime tenSecondsLater = now.plusSeconds(10);

    long diff = now.until(tenSecondsLater, ChronoUnit.SECONDS);

    assertEquals(diff, 10);
}

Temporal#untilTemporalUnit#between は、同じ機能の2つの異なるAPIです。

3. 外部ライブラリ

3.1. JodaTime

JodaTimeを使用して比較的簡単な実装を行うこともできます。


    joda-time
    joda-time
    2.9.9

Maven Centralから最新バージョンのJoda-timeを入手できます。

LocalDateの場合:

@Test
public void givenTwoDatesInJodaTime_whenDifferentiating_thenWeGetSix() {
    LocalDate now = LocalDate.now();
    LocalDate sixDaysBehind = now.minusDays(6);

    Period period = new Period(now, sixDaysBehind);
    long diff = Math.abs(period.getDays());

    assertEquals(diff, 6);
}

同様に、LocalDateTimeの場合は次のようになります。

@Test
public void givenTwoDateTimesInJodaTime_whenDifferentiating_thenWeGetSix() {
    LocalDateTime now = LocalDateTime.now();
    LocalDateTime sixMinutesBehind = now.minusMinutes(6);

    Period period = new Period(now, sixMinutesBehind);
    long diff = Math.abs(period.getDays());
}

3.2. Date4J

Date4jは、この場合、TimeZone.を明示的に提供する必要があることに注意せずに、単純で単純な実装も提供します。

Mavenの依存関係から始めましょう:


    com.darwinsys
    hirondelle-date4j
    1.5.1

標準のDateTimeを使用した簡単なテストは次のとおりです。

@Test
public void givenTwoDatesInDate4j_whenDifferentiating_thenWeGetSix() {
    DateTime now = DateTime.now(TimeZone.getDefault());
    DateTime sixDaysBehind = now.minusDays(6);

    long diff = Math.abs(now.numDaysFrom(sixDaysBehind));

    assertEquals(diff, 6);
}

4. 結論

このチュートリアルでは、プレーンJavaと外部ライブラリを使用して、日付の差を計算するいくつかの方法(時間ありとなし)を説明しました。

記事の完全なソースコードはover on GitHubで入手できます。