SimpleDateFormatとDateTimeFormatterの違いってなんだ??
自分がこの前書いた記事で、SimpleDateFormatとDateTimeFormatterを使用した。
どちらも日付時刻フォーマッターで、一体何が違うのか把握できていなかったので、調べてみた。
インスタンス生成の違い
newするか、用意されているメソッドを使用するかの違いがある。
SimpleDateFormatの場合
SimpleDateFormatのインスタンス生成は、newして生成する。
スレッドセーフではない。
そのため、マルチスレッド処理の場合、使用する直前で毎回インスタンスを生成することが必要。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
DateTimeFormatterの場合
DateTimeFormatterのインスタンス生成は、ofPatternメソッドで生成する。
スレッドセーフ。
SimpleDateFormatと違って、マルチスレッド処理のとき、使うたびにインスタンスを生成するということが必要ない。
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSS");
parse(解析)
StringをSimpleDateFormatとDateTimeFormatterを使って変換してみる。
SimpleDateFormatの場合
String → Dateに変換する処理。
parseメソッドにString型を引数として渡すのみ。
ParseExceptionの例外処理が必要だけど、下の例では省略。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
Date date = sdf.parse("2018/05/14 12:34:56.123");
// Mon May 14 12:34:56 UTC 2018
System.out.println(date);
DateTimeFormatterの場合
String → TemporalAccessorに変換する処理。
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSS");
TemporalAccessor ta = dtf.parse("2018/05/14 12:34:56.123");
// {},ISO resolved to 2018-05-14T12:34:56.123
System.out.println(ta);
TemporalAccessorってなに…?ってなった。出力結果も"ISO resolved to ~~"とかついている。
LocalDateTimeの親インターフェースらしい。他にもLocalDate, LocalTime, ZonedDateTimeの親にあたる。
なので、こんなことが可能。
※ 自分で書いておいて「だからなに…?」ってなっていますが、備忘録として記載。
TemporalAccessor tAccessor = LocalDateTime.of(2018, 5, 14, 12, 34, 56);
DateTimeFommaterでparseする場合、LocalDateTimeのparseメソッドが使用されているパターンが多いと思われる。
下のようになる。こちらのほうが使用頻度高そうなので覚えておきたい。
(String → LocalDateTimeに変換する処理。)
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSS");
LocalDateTime date = LocalDateTime.parse("2018/05/14 12:34:56.123", dtf);
// 2018-05-14T12:34:56.123
System.out.println(date);
format(整形)
SimpleDateFormatとDateTimeFormatterをその名の通りフォーマットしてみる。
SimpleDateFormatの場合
Date→Stringに変換する処理。
formatメソッドにjava.util.Date型を引数として渡す。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
Date date = sdf.parse("2018/05/14 12:34:56.123");
// Mon May 14 12:34:56 UTC 2018
System.out.println(date);
String str = sdf.format(date);
// 2018/05/14 12:34:56.123
System.out.println(str);
DateTimeFormatterの場合
formatメソッドにTemporalAccessorを引数として渡す。
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSS");
LocalDateTime date = LocalDateTime.parse("2018/05/14 12:34:56.123", dtf);
// 2018-05-14T12:34:56.123
System.out.println(date);
String str = dtf.format(date);
// 2018/05/14 12:34:56.123
System.out.println(str);
まとめ
だらだらと書いてしまったが、わかったことをまとめると、
SimpleDateFormat | DateTimeFormatter | |
---|---|---|
型 | java.util.Dateへの変換 | TemporalAccessorへの変換(LocalDateTime, LocalDate, LocalTime, ZonedDateTimeなど) |
インスタンス生成 | new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS") |
DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSS") |
スレッドセーフ? | × | ◯ |
parse |
dtf.parse(str) java.util.Dateになる。 |
dtf.parse(str) TemporalAccessorになる。 LocalDateTimeなどのparseメソッドのほうが使いやすい。 |
format | sdf.format(date) |
dtf.format(TemporalAccessor) |
Javaの日付/時刻の扱いはやっぱり難しい。
PHPはこんなに難しくなったような気がする。
(日付/時刻を扱ったことがあまりないからそう思っているだけかも…)