#java8
#DateAndTimeAPI
#Timestamp

JDBCのTimestampからDate And Time APIへ変換したい

DBから取得した時刻の値をDate And Time APIで扱う際に迷ったため、メモ。

変換用にtoLocalDateTime()がある

方法はシンプル。
上記のメソッドを呼び出すことでLocalDateTimeにささっと変換できる。

DB値をDateAndTimeAPIで扱う
    Timestamp ts = rs.getTimestamp("timestampのカラム名"); // rsはResultSet
    LocalDateTime ldt = timestamp.toLocalDateTime();
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd");  // 文字列フォーマットもDate And Time APIで
    String dateStr = dtf.format(ldt);

上記で文字列フォーマットまでをDate And Time APIで行うことが可能。

何故Date And Time APIを使うのか?

現在のところJDBCはDate And Time APIに未対応なので、上記のような方法で変換をしているが、そもそも何故そこまでしてDate And Time APIを使いたいのか?
理由は、自分は文字列フォーマットによくSimpleDateFormatを使っているが、これがDate And Time APIのDateTimeFormatterが軽量で扱いやすいから。
個人的に検証はしておらず検証を行っているサイトの受け売りだが、SimpleDateFormatはスレッドセーフでない、かつ、インスタンス生成に時間がかかるため、あまりおすすめできないとのこと。
その点、Date And Time APIのDateTimeFormatterはスレッドセーフ、かつ、インスタンス生成も軽いためJava8を使っているならDate And Time APIを使うべき!とのこと。
ちなみにベンチマークテストの結果は、フォーマット、解析処理共にDateTimeFormatterの方が早かったそう。
個人的にはこの結果を信じて、特にSimpleDateFormatでフォーマット処理をしていた箇所は、Date And Time APIに置き換えを考えている。

引用元:http://www.ne.jp/asahi/hishidama/home/tech/java/DateTimeFormatter.html

Date And Time APIからDBへの登録は?

変換用にvalueOf(LocalDateTime)がある

Date And Time APIからJDBCの日付型への型変換も容易にできる。

DateAndTimeAPIの日付型からJDBCの日付型へ
    LocalDateTime ldt = LocalDateTime.now();
    Timestamp ts = Timestamp.valueOf(ldt);

java.sql.Date型への変換の際は、Date And Time APIの対応する型をvalueOfすればよい。

java.sql.Date型へ
    LocalDate ld = LocalDate.now();
    java.sql.Date date = java.sql.Date.valueOf(ld);

異なる精度への変換

画面入力上、日付文字列をフォーマット:yyyy/MM/ddで入力したものを、DBへTimestampで登録したい場合がある。
この場合は、日付文字列を一度日付を扱うLocalDateへ変換、LocalDateのatTime()を使ってLocalDateTimeに変換する。

日付文字列をLocalDateTimeへ
    String strDate = "2017/09/09";
    LocalDateTime date = null;
    DateTimeFormatter sdf = DateTimeFormatter.ofPattern("yyyy/MM/dd");
    date = LocalDate.parse(startDate, sdf).atTime(0, 0);

この際、atTime()は引数として時間を指定する必要がある。特に時間に関して取り決めがなければ、上記のように0時0分0秒を表す値を入力すれば問題ない。(引数にLocalTimeを指定することも可能)