タイトルの通りSimpleDateFormatはスレッドセーフではないことを確認してみた。
反対にDateTimeFormatterはスレッドセーフとのことなので書き方の違いも合わせて比較してみた。
サンプルコード
マルチスレッドでの実行を想定して以下のコードを実行してみる。
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
/**
* {@link SimpleDateFormat}と{@link DateTimeFormatter}の比較
*/
public class CompareSample {
private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ISO_DATE;
public void execute() {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
String sdf = this.useSimpleDateFormat(2016, 11, 7);
String dtf = this.useDateTimeFormatter(2016, 11, 7);
System.out.println("SimpleDateFormat=" + sdf + ", DateTimeFormatter=" + dtf + ", equals=" + sdf.equals(dtf));
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
String sdf = this.useSimpleDateFormat(2017, 12, 17);
String dtf = this.useDateTimeFormatter(2017, 12, 17);
System.out.println("SimpleDateFormat=" + sdf + ", DateTimeFormatter=" + dtf + ", equals=" + sdf.equals(dtf));
}
});
t1.start();
t2.start();
}
private String useSimpleDateFormat(int year, int month, int date) {
Calendar cal = Calendar.getInstance();
cal.set(year, month - 1, date);
return SIMPLE_DATE_FORMAT.format(cal.getTime());
}
private String useDateTimeFormatter(int year, int month, int date) {
LocalDate localDate = LocalDate.of(year, month, date);
return DATE_TIME_FORMATTER.format(localDate);
}
}
import org.junit.Test;
/**
* {@link CompareSample}のテスト
*/
public class CompareSampleTest {
@Test
public void testExecute() {
CompareSample test = new CompareSample();
test.execute();
}
}
実行結果
どちらも「2016-11-07」または「2017-12-17」であればOKだが、
SimpleDateFormatはたまにおかしな値を返すことがわかる。
SimpleDateFormat=2017-12-17, DateTimeFormatter=2017-12-17, equals=true
SimpleDateFormat=2016-11-07, DateTimeFormatter=2016-11-07, equals=true
SimpleDateFormat=2016-11-07, DateTimeFormatter=2016-11-07, equals=true
SimpleDateFormat=2017-11-07, DateTimeFormatter=2017-12-17, equals=false
SimpleDateFormat=2016-11-17, DateTimeFormatter=2016-11-07, equals=false
SimpleDateFormat=2017-12-17, DateTimeFormatter=2017-12-17, equals=true
SimpleDateFormat=2016-11-17, DateTimeFormatter=2016-11-07, equals=false
SimpleDateFormat=2017-12-17, DateTimeFormatter=2017-12-17, equals=true
SimpleDateFormat=2017-12-17, DateTimeFormatter=2017-12-17, equals=true
SimpleDateFormat=2016-11-17, DateTimeFormatter=2016-11-07, equals=false
SimpleDateFormat=2017-12-17, DateTimeFormatter=2017-12-17, equals=true
SimpleDateFormat=2016-11-07, DateTimeFormatter=2016-11-07, equals=true
SimpleDateFormat=2016-11-07, DateTimeFormatter=2016-11-07, equals=true
SimpleDateFormat=2017-12-17, DateTimeFormatter=2017-12-17, equals=true
SimpleDateFormat=2016-11-07, DateTimeFormatter=2016-11-07, equals=true
SimpleDateFormat=2017-12-17, DateTimeFormatter=2017-12-17, equals=true
SimpleDateFormat=2016-11-07, DateTimeFormatter=2016-11-07, equals=true
SimpleDateFormat=2017-12-17, DateTimeFormatter=2017-12-17, equals=true
SimpleDateFormat=2016-11-07, DateTimeFormatter=2016-11-07, equals=true
SimpleDateFormat=2017-12-17, DateTimeFormatter=2017-12-17, equals=true