Javaで時間のない日付を取得する
1. 前書き
この短いチュートリアルでは、Javaで時間をかけずにDateを取得する方法を示します。
Java8で新しいtimeAPIがリリースされた後、状況が少し変わったため、Java8の前後でこれを行う方法を示します。
2. Java 8より前
Java 8より前は、Joda-timeのようなサードパーティのライブラリを使用していない限り、時間なしでDateを取得する直接的な方法はありませんでした。
これは、the Date class in Java is a representation of a specific instant in time, expressed in millisecondsが原因です。 したがって、これにより、Dateの時間を無視することができなくなります。
次のセクションでは、この問題に取り組むためのいくつかの一般的な回避策を示します。
2.1. Calendarの使用
時間なしでDateを取得する最も一般的な方法の1つは、use the Calendar class to set the time to zeroを使用することです。 これを行うことにより、1日の始めに設定された時刻で、クリーンな日付を取得します。
コードで見てみましょう:
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
ご覧のとおり、時刻がゼロに設定された完全な日付が返されますが、we can’t ignore the timeです。
また、返される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. フォーマッタの使用
これを行う別の方法は、formatting a Date into a String without the time and then convert that String back to a 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の新しい時間APIのリリースにより、時間なしで日付を取得する簡単な方法があります。 この新しいAPIがもたらした新機能の1つは、時間の有無に関係なく日付を処理したり、時間のみを処理したりするためのクラスがいくつかあることです。
この記事では、クラスLocalDateに焦点を当てます。これは、必要なもの、つまり時刻のない日付を正確に表します。
この例でそれを見てみましょう:
public static LocalDate getLocalDate() {
return LocalDate.now();
}
このメソッドは、次の日付表現を持つLocalDateオブジェクトを返します。
2018-06-23
ご覧のとおり、日付the time is completely ignoredのみが返されます。
繰り返しますが、前と同じようにテストして、このメソッドが期待どおりに機能することを確認しましょう。
@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 should be always the preferred optionを使用します。これは、時間のない日付を処理するための特定の表現があるためです。
いつものように、例の完全なソースコードはover on GitHubで入手できます。