Javaで時間なしで日付を取得する

1前書き

この短いチュートリアルでは、Javaで Date を時間なしで取得する方法を説明します。

Java 8で新しいtime APIがリリースされた後は状況が少し変わったため、Java 8の前後にこれを行う方法を示します。

2 Java 8 より前

Java 8より前は、Joda-timeのようなサードパーティ製のライブラリを使用していない限り、時間なしで Date を取得する直接的な方法はありませんでした。

これは、** Javaの Date クラスがミリ秒単位で表される特定の瞬間の表現であるためです。したがって、これは Date の時間を無視することを不可能にします。

次のセクションでは、この問題に対処するための一般的な回避策をいくつか示します。

2.1. Calendar を使う

時間なしで Date を取得する最も一般的な方法の1つは、 Calendar クラスを使用して時間をゼロに設定することです** 。これを行うことで、その日の初めに設定された時間で、きれいな日付が得られます。

コードで見てみましょう。

public static Date getDateWithoutTimeUsingCalendar() {
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.HOUR__OF__DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    return calendar.getTime();
}

このメソッドを呼び出すと、次のような日付が得られます。

Sat Jun 23 00:00:00 CEST 2018

ご覧のとおり、これは時間をゼロに設定した完全な日付を返しますが、 時間を無視することはできません

また、返される Date に時間が設定されていないことを確認するために、次のテストを作成できます。

@Test
public void whenGettingDateWithoutTimeUsingCalendar__thenReturnDateWithoutTime() {
    Date dateWithoutTime = DateWithoutTime.getDateWithoutTimeUsingCalendar();

    Calendar calendar = Calendar.getInstance();
    calendar.setTime(dateWithoutTime);
    int day = calendar.get(Calendar.DAY__OF__MONTH);

    calendar.setTimeInMillis(dateWithoutTime.getTime() + MILLISECONDS__PER__DAY - 1);
    assertEquals(day, calendar.get(Calendar.DAY__OF__MONTH));

    calendar.setTimeInMillis(dateWithoutTime.getTime() + MILLISECONDS__PER__DAY);
    assertNotEquals(day, calendar.get(Calendar.DAY__OF__MONTH));
}

ご覧のとおり、1日のミリ秒から1を引いた日を日付に加算しても同じ日が得られますが、1日を加算すると次の日になります。

2.2. フォーマッタを使う

これを行う別の方法は、 Date を時間なしで String にフォーマットしてから、その String Date ** に変換することです。 String は時刻なしでフォーマットされているので、 Date に変換された時刻はゼロに設定されます。

仕組みを確認するために実装しましょう。

public static Date getDateWithoutTimeUsingFormat()
  throws ParseException {
    SimpleDateFormat formatter = new SimpleDateFormat(
      "dd/MM/yyyy");
    return formatter.parse(formatter.format(new Date()));
}

この実装は前のセクションで示したメソッドと同じものを返します。

Sat Jun 23 00:00:00 CEST 2018

繰り返しますが、返された Date に時間がないことを確認するために、以前と同じテストを使用できます。

3 Java 8 を使用する

Java 8で新しいtime APIがリリースされたため、時間なしで日付を取得するためのより簡単な方法があります。この新しいAPIがもたらした新機能の1つは、時間を指定してまたは指定せずに日付を処理するクラス、または時間を指定してのみ実行するクラスさえあることです。

この記事では、 LocalDate というクラスに焦点を当てます。これは、必要なものを正確に表します。時間のない日付です。

この例を見てみましょう。

public static LocalDate getLocalDate() {
    return LocalDate.now();
}

このメソッドは、この日付表現を持つ LocalDate オブジェクトを返します。

2018-06-23

ご覧のとおり、日付を返すだけです。 時間は完全に無視されます

繰り返しますが、このメソッドが期待どおりに機能することを確認するために以前と同じようにテストしましょう。

@Test
public void whenGettingLocalDate__thenReturnDateWithoutTime() {
    LocalDate localDate = DateWithoutTime.getLocalDate();

    long millisLocalDate = localDate
      .atStartOfDay()
      .toInstant(OffsetDateTime
        .now()
        .getOffset())
      .toEpochMilli();

    Calendar calendar = Calendar.getInstance();

    calendar.setTimeInMillis(
      millisLocalDate + MILLISECONDS__PER__DAY - 1);
    assertEquals(
      localDate.getDayOfMonth(),
      calendar.get(Calendar.DAY__OF__MONTH));

    calendar.setTimeInMillis(millisLocalDate + MILLISECONDS__PER__DAY);
    assertNotEquals(
      localDate.getDayOfMonth(),
      calendar.get(Calendar.DAY__OF__MONTH));
}

4結論

この記事では、Javaで Date を取得する方法について説明しました。

最初に、Java 8より前、そしてJava 8を使用する前にそれを行う方法を示しました。

この記事で実装されている例でわかるように、 Java 8を使用することは、常に優先オプション である必要があります。

いつものように、例の完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/java-dates[GitHubで利用可能]です。