Javaで日付に時間を追加する

Javaで日付に時間を追加する

1. 概要

Java 8より前は、java.util.DateはJavaで日時値を表すために最も一般的に使用されるクラスの1つでした。

次に、Java 8ではjava.time.LocalDateTimejava.time.ZonedDateTime.が導入されました。Java8では、java.time.Instant.を使用してタイムライン上の特定の時刻を表すこともできます。

このチュートリアルでは、add or subtract n hours from a given date-time in Javaについて学習します。 最初にいくつかの標準的なJava日時関連クラスを見てから、いくつかのサードパーティオプションを紹介します。

Java 8 DateTime APIの詳細については、this articleを読むことをお勧めします。

2. java.util.Date

Java 7以下を使用している場合は、ほとんどの日時関連の処理にjava.util.Dateクラスとjava.util.Calendarクラスを使用できます。

特定のDateオブジェクトにn時間を追加する方法を見てみましょう。

public Date addHoursToJavaUtilDate(Date date, int hours) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.HOUR_OF_DAY, hours);
    return calendar.getTime();
}

Calendar.HOUR_OF_DAY is referring to a 24-hour clockに注意してください。

上記のメソッドは、新しいDateオブジェクトを返します。その値は、それぞれhoursの正の値と負の値のどちらを渡すかに応じて、(date + hours)または(date – hours)のいずれかになります。

Java 8アプリケーションがあるが、それでもjava.util.Dateインスタンスを処理したいとします。

このような場合、次の代替アプローチを選択できます。

  1. java.util.DatetoInstant()メソッドを使用して、Dateオブジェクトをjava.time.Instantインスタンスに変換します

  2. plus()メソッドを使用して、特定のDurationjava.time.Instantオブジェクトに追加します

  3. java.time.Instantオブジェクトをjava.util.Date.from()メソッドに渡すことにより、java.util.Dateインスタンスを回復します

このアプローチを簡単に見てみましょう。

@Test
public void givenJavaUtilDate_whenUsingToInstant_thenAddHours() {
    Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0)
      .getTime();
    Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 7, 0)
      .getTime();

    assertThat(Date.from(actualDate.toInstant().plus(Duration.ofHours(2))))
      .isEqualTo(expectedDate);
}

ただし、it’s always recommended to use the new DateTime API for all applications on Java 8 or higher versions.に注意してください

3. java.time.LocalDateTime/ZonedDateTime

Java 8以降では、java.time.LocalDateTime or java.time.ZonedDateTimeインスタンスに時間を追加するのは非常に簡単で、plusHours()メソッドを使用します。

@Test
public void givenLocalDateTime_whenUsingPlusHours_thenAddHours() {
    LocalDateTime actualDateTime = LocalDateTime
      .of(2018, Month.JUNE, 25, 5, 0);
    LocalDateTime expectedDateTime = LocalDateTime.
      of(2018, Month.JUNE, 25, 10, 0);

    assertThat(actualDateTime.plusHours(5)).isEqualTo(expectedDateTime);
}

数時間減算したい場合はどうしますか?

時間の負の値をplusHours()メソッドに渡すと、問題なく動作します。 ただし、minusHours()メソッドを使用することをお勧めします。

@Test
public void givenLocalDateTime_whenUsingMinusHours_thenSubtractHours() {
    LocalDateTime actualDateTime = LocalDateTime
      .of(2018, Month.JUNE, 25, 5, 0);
    LocalDateTime expectedDateTime = LocalDateTime
      .of(2018, Month.JUNE, 25, 3, 0);

    assertThat(actualDateTime.minusHours(2)).isEqualTo(expectedDateTime);

}

java.time.ZonedDateTimeplusHours()メソッドとminusHours()メソッドは、まったく同じように機能します。

4. java.time.Instant

ご存知のとおり、Java 8 DateTime APIで導入されたjava.time.Instantは、タイムライン上の特定の瞬間を表しています。

Instantオブジェクトに数時間を追加するには、そのplus()メソッドをjava.time.temporal.TemporalAmountとともに使用します。

@Test
public void givenInstant_whenUsingAddHoursToInstant_thenAddHours() {
    Instant actualValue = Instant.parse("2018-06-25T05:12:35Z");
    Instant expectedValue = Instant.parse("2018-06-25T07:12:35Z");

    assertThat(actualValue.plus(2, ChronoUnit.HOURS))
      .isEqualTo(expectedValue);
}

同様に、minus()メソッドは、特定のTemporalAmountを減算するために使用できます。

5. Apache CommonsDateUtils

Apache Commons LangライブラリのDateUtilsクラスは、staticaddHours()メソッドを公開します。

public static Date addHours(Date date, int amount)

このメソッドは、java.util.Dateオブジェクトとそれに追加したいamountを取り込みます。このオブジェクトの値は、正または負のいずれかになります。

新しいjava.util.Dateオブジェクトが結果として返されます。

@Test
public void givenJavaUtilDate_whenUsingApacheCommons_thenAddHours() {
    Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0)
      .getTime();
    Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 7, 0)
      .getTime();

    assertThat(DateUtils.addHours(actualDate, 2)).isEqualTo(expectedDate);
}

Apache Commons Langの最新バージョンはMaven Central.で入手できます。

6. ジョーダ時間

Joda TimeはJava 8 DateTime APIの代替であり、独自のDateTime実装を提供します。

そのDateTime関連クラスのほとんどは、plusHours()およびminusHours()メソッドを公開して、DateTimeオブジェクトから指定された時間数を加算または減算するのに役立ちます。

例を見てみましょう:

@Test
public void givenJodaDateTime_whenUsingPlusHoursToDateTime_thenAddHours() {
    DateTime actualDateTime = new DateTime(2018, 5, 25, 5, 0);
    DateTime expectedDateTime = new DateTime(2018, 5, 25, 7, 0);

    assertThat(actualDateTime.plusHours(2)).isEqualTo(expectedDateTime);
}

Maven Centralで利用可能な最新バージョンのJoda Timeを簡単に確認できます。

7. 結論

このチュートリアルでは、標準のJava日時値から特定の時間数を加算または減算するいくつかの方法について説明しました。

また、いくつかのサードパーティライブラリを代替手段として検討しました。 いつものように、完全なソースコードはover on GitHubで利用できます。