JDK 8提供了新的时间日期库,相关实现位于java.time
包下。这里记录下基本用法,大致列举下常用的时间日期相关操作,
常见用法
当前时间获取
LocalDateTime dateTime = LocalDateTime.now();
LocalDate date = LocalDate.now();
LocalTime time = LocalTime.now();
LocalDateTime
包含日期与具体时间,LocalDate
只包含日期,LocalTime
只包含时间。看到这个类定义,顺带想起Python中提供的对应模块,有点接近,可以对照看一下,
now = datetime.datetime.now()
date = now.date()
time = now.time()
静态构造
LocalDateTime
等类提供了一组静态函数用以构建对象,
LocalDateTime end = LocalDateTime.of(2012, 12, 21, 3, 14, 35);
通过Java的函数重载机制可以在多种精度上构建事件对象。
格式化输出与字符串解析
时间格式化通过DateTimeFormatter
类来实现,默认提供了一组预定义的转化定义,也可以通过字符串来进行构建,
LocalDateTime now = LocalDateTime.now();
now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LocalDateTime end = LocalDateTime.parse("2012-12-21 03:14:35", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
日期时间与当前时刻的互相转化
以前获取当前时刻的毫秒数通过下面代码进行获取,
System.currentTimeMillis();
java.time
提供了Instant
类来获取同样的时刻点,
Instant.now().toEpochMilli();
LocalDateTime
与Instant
之间可以互相进行转化,
LocalDateTime now = LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault());
now.toInstant(ZoneOffset.UTC).toEpochMilli();
Instant
可以从时刻进行构建,
Instant.ofEpochMilli(System.currentTimeMillis());
时间计算
时间相关的计算主要有两种,一种为给定时间和变化量,获取运算后的时间,
LocalDateTime now = LocalDateTime.now();
now = now.plus(1, ChronoUnit.DAYS);
LocalDateTime
中提供了一组plus
、minus
、with
接口用于计算。
另外一种为计算两个时间之间的差距,
LocalDateTime start = LocalDateTime.of(2018, 1, 1, 0, 0, 0);
LocalDateTime end = LocalDateTime.of(2018, 1, 2, 1, 0, 1);
Duration duration = Duration.between(start, end);
duration.toDays();
duration.toHours();
duration.toMinutes();
duration.getSeconds();
start.until(end, ChronoUnit.DAYS);
start.until(end, ChronoUnit.HOURS);
start.until(end, ChronoUnit.SECONDS);
start.until(end, ChronoUnit.HOURS);
如上两种写法都能够获得差值。通过Duration
可能会更有利于后续的运算处理。
时区处理
LocalDateTime
等表示的是本地时间,不带时区信息。与时间相关的是ZoneDateTime
相关类,
ZonedDateTime now = ZonedDateTime.of(LocalDateTime.now(), ZoneId.of("Asia/Shanghai"));
同一时刻在不同时区下的时间展示处理,
long now = System.currentTimeMillis();
LocalDateTime start = LocalDateTime.ofInstant(Instant.ofEpochMilli(now), ZoneId.of("Asia/Shanghai"));
LocalDateTime end = LocalDateTime.ofInstant(Instant.ofEpochMilli(now), ZoneId.of("Asia/Tokyo"));
System.out.println(Duration.between(start, end).toHours());
注意事项
java.time
中提供的类基本都是线程安全的,因此可以避免掉先前SimpleDateFormat
线程相关问题。在新项目中,时间处理最好都切换到新的API下。