1、新老 API 对比
使用 LocalDate 、LocalTime 、LocalDateTime
原有的日期 API 如:Date、SimpleDateFormat、TimeZone 这些都是可变的对象,即在相互线程之间的修改是掺杂在一起的,是线程不安全的。
LocalDate、LocalTime、LocalDateTime 类的实例是不可变的对象,当改变时,会产生一个新的实例。他们分别表示使用 ISO-8601日历系统的日期、时间、日期和时间,提供了简单的日期或时间,并不包含当前的时间信息。也不包含与时区相关的信息。新日期 API 的转换器使用 DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:mm:ss”);
注:ISO-8601日历系统是国际标准化组织制定的现代公民的日期和时间的表示法
2、演示多线程字符串解析成日期
public void testSimpleDateFormat() throws Throwable {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
Callable<Date> task = new Callable<Date>() {
@Override
public Date call() throws Exception {
return simpleDateFormat.parse("20161218");
}
};
ExecutorService pool = Executors.newFixedThreadPool(10);
List<Future<Date>> results = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
results.add(pool.submit(task));
}
for (Future<Date> future : results) {
log.info(future.get().toString());
}
}
多次并发执行下,出现如下 juc 异常:
3、演示新日期 API
Date 换成 localDate
SimpleDateFormat 换成 DateTimeFormatter
simpleDateFormat.parse(“20161218”); 换成 LocalDate.parse(“20161218”, dtf);
public void testSimpleDateFormat() throws Throwable {
// 格式转换器
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
// 模拟多线程
Callable<LocalDate> task = new Callable<LocalDate>() {
@Override
public LocalDate call() throws Exception {
return LocalDate.parse("20161218", dtf);
}
};
ExecutorService pool = Executors.newFixedThreadPool(10);
List<Future<LocalDate>> results = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
results.add(pool.submit(task));
}
for (Future<LocalDate> future : results) {
log.info(future.get().toString());
}
}
4、新日期 API 逐个详解
LocalDate 、LocalTime、LocalDateTime 的使用方式都一样。
4.1、获取当前系统时间创建 Localxxx 对象
public void testLocalDateTime() {
// 获取当前系统时间
LocalDateTime ldt = LocalDateTime.now();
log.info(ldt.toString());
}
4.2、自己指定时间创建 Localxxx 对象
public void testLocalDateTime() {
// 自己指定时间
LocalDateTime ldt2 = LocalDateTime.of(2015, 10, 19, 13, 22, 33);
log.info(ldt2.toString());
}