java.util.Dateとjava.sql.Dateとjava.time.LocalDateのややこしい関係
環境
JDK 21
Java 8以降であれば、バージョンが違っていても同じだと思います。たぶん。
各クラスの1行説明
-
java.util.Date
- Javaの初期から存在する日時クラス(時分秒も持つ)
-
java.sql.Date
- JDBCで利用する日付クラス(時分秒は持たない)
-
java.time.LocalDate
- Java 8から導入された日付クラス(時分秒は持たない)
通常の業務ロジックを書くときは、基本的にはjava.time.LocalDate
を使うことがほとんどです。
しかし、古いライブラリやロジックではjava.util.Date
、DB周りの込み入ったロジックではjava.sql.Date
を使ったりすることもあるかと思います。
java.util.Date
と同様にJavaの初期から存在するクラスでjava.util.Calendar
があります。古いロジックで見ることがあるかもですが、現在ではほとんど使う機会が無いと思います。
java.util.Date
とjava.sql.Date
の関係
java.sql
パッケージには、日時を表すクラスが3つあります。
-
java.sql.Date
- 日付(時分秒を持たない)
- PostgreSQLで言うところの
DATE
型に対応
-
java.sql.Time
- 時分秒(日付を持たない)
- PostgreSQLで言うところの
TIME
型に対応
-
java.sql.Timestamp
- 日時(日付・時分秒すべてを持つ)
- PostgreSQLで言うところの
TIMESTAMP
型に対応
PostgreSQLの型については公式ドキュメントを参照
そして、これら3つのクラスは全てjava.util.Date
のサブクラスです。
日付・時分秒すべてを持つjava.util.Date
のサブクラスなのに、java.sql.Date
は時分秒を持たない、java.sql.Time
は日付を持たないのは違和感がありますね。何故か分かりませんが、こうなっています。
特にjava.sql.Date
はjava.util.Date
とクラス名も一緒なので、使うときはimport間違いに気をつけてください。
java.util.Date
とjava.time.LocalDate
の関係
前述の通り、Java初期からあったのがjava.util.Date
で、java.time.LocalDate
は後からJava 8で導入されました。
java.util.Date
は以下のような問題がありました。
- ミュータブルである
- 「2日後」「3時間後」のような日時の計算が面倒
- 「◯ヶ月◯日間」のような期間を扱えない
-
java.util.Date
を文字列フォーマットするSimpleDateFormat
クラスがスレッドセーフでない
そこで新しく登場したのがjava.time
パッケージです。上記の問題を解決した、以下のような特徴を備えています。
- イミュータブルである
- 日時を計算するメソッド
- 期間を扱うクラス
- スレッドセーフな
DateTimeFormatter
クラス
java.time
パッケージにはかなり多くのクラスがあります。よく使うものは以下のとおりです。
-
LocalDate
- 日付(時分秒を持たない)
-
LocalTime
- 時分秒(日付を持たない)
-
LocalDateTime
- 日時(日付・時分秒すべてを持つ)
java.util.Date
をjava.time.LocalDateTime
に変換することは可能ですが、ちょっぴり面倒です。
import java.util.Date;
import java.time.LocalDateTime;
import java.time.ZoneId;
public class DateConverter {
public static void main(String[] args) {
Date date = new Date();
// Date -> LocalDateTime
LocalDateTime localDateTime = date.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime();
System.out.println("LocalDateTime: " + localDateTime);
// LocalDateTime -> Date
Date convertedDate = Date.from(localDateTime
.atZone(ZoneId.systemDefault())
.toInstant());
System.out.println("Date: " + convertedDate);
}
}
java.sql.Date
とjava.time.LocalDate
の関係
java.sql.Date
とjava.time.LocalDate
は、変換するメソッドが用意されています。
import java.sql.Date;
import java.time.LocalDate;
public class DateConverter {
public static void main(String[] args) {
Date date = new Date(System.currentTimeMillis());
// Date -> LocalDate
LocalDate localDate = date.toLocalDate();
System.out.println("Converted LocalDate: " + localDate);
// LocalDate -> Date
Date date2 = Date.valueOf(localDate);
System.out.println("Converted Date: " + date2);
}
}
java.sql.Time
とjava.time.LocalTime
、java.sql.Timestamp
とjava.time.LocalDateTime
も同様に変換できます。
Discussion