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();

LocalDateTimeInstant之间可以互相进行转化,

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中提供了一组plusminuswith接口用于计算。

另外一种为计算两个时间之间的差距,

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下。

参考