Java 中求两日期的差量
本文简短地介绍java 中多种方式求两个日期的差量。
使用java.util.Date
首先我们使用java api中的java.util.Date类,计算两日期之间天数:
@Test
public void givenTwoDatesBeforeJava8_whenDifferentiating_thenWeGetSix()
throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy", Locale.ENGLISH);
Date firstDate = sdf.parse("06/24/2017");
Date secondDate = sdf.parse("06/30/2017");
long diffInMillies = Math.abs(secondDate.getTime() - firstDate.getTime());
long diff = TimeUnit.DAYS.convert(diffInMillies, TimeUnit.MILLISECONDS);
assertEquals(diff, 6);
}
通过getTime方法获得日期的毫秒数,然后通过TimeUnit转换为天数。
使用java 8 中java.time包中Period和Duration
结合Period 和 Duration使用 LocalDate, LocalDateTime 计算差更直观,它们表示日期(不带或带时间):
LateDate:
@Test
public void givenTwoDatesInJava8_whenDifferentiating_thenWeGetSix() {
LocalDate now = LocalDate.now();
LocalDate sixDaysBehind = now.minusDays(6);
Period period = Period.between(now, sixDaysBehind);
int diff = period.getDays();
assertEquals(diff, 6);
}
LocalDateTime:
@Test
public void givenTwoDateTimesInJava8_whenDifferentiating_thenWeGetSix() {
LocalDateTime now = LocalDateTime.now();
LocalDateTime sixMinutesBehind = now.minusMinutes(6);
Duration duration = Duration.between(now, sixMinutesBehind);
long diff = Math.abs(duration.toMinutes());
assertEquals(diff, 6);
}
使用java.time.temporal.ChronoUnit
java 8 中时间API表示日期作为单元,如秒、天等,在TemporalUnit接口中定义。每个单元提供between方法实现,用于计算两个temporal对象之间的时间量。举例,计算LocalDateTime之间秒数:
@Test
public void givenTwoDateTimesInJava8_whenDifferentiatingInSeconds_thenWeGetTen() {
LocalDateTime now = LocalDateTime.now();
LocalDateTime tenSecondsLater = now.plusSeconds(10);
long diff = ChronoUnit.SECONDS.between(now, tenSecondsLater);
assertEquals(diff, 10);
}
ChronoUnit通过实现TemporalUnit 接口提供一组具体时间单元,强烈建议通过静态方式导入ChronoUnit枚举值使代码更直观:
import static java.time.temporal.ChronoUnit.SECONDS;
// omitted
long diff = SECONDS.between(now, tenSecondsLater);
我们也可以传递两个兼容的temporal对象至between方法中,甚至ZonedDateTime.ZonedDateTime的强大之处在于,即使它们被设置为不同的时区,计算也能正常工作:
@Test
public void givenTwoZonedDateTimesInJava8_whenDifferentiating_thenWeGetSix() {
LocalDateTime ldt = LocalDateTime.now();
ZonedDateTime now = ldt.atZone(ZoneId.of("America/Montreal"));
ZonedDateTime sixMinutesBehind = now
.withZoneSameInstant(ZoneId.of("Asia/Singapore"))
.minusMinutes(6);
long diff = ChronoUnit.MINUTES.between(sixMinutesBehind, now);
assertEquals(diff, 6);
}
使用java.time.temporal.Temporal until()方法
任何Temporal对象,如LocalDate or ZonedDateTime,提供了until方法用于计算日期差:
@Test
public void givenTwoDateTimesInJava8_whenDifferentiatingInSecondsUsingUntil_thenWeGetTen() {
LocalDateTime now = LocalDateTime.now();
LocalDateTime tenSecondsLater = now.plusSeconds(10);
long diff = now.until(tenSecondsLater, ChronoUnit.SECONDS);
assertEquals(diff, 10);
}
Temporal#until 和 TemporalUnit#between 两者api不同,但实现功能相同,所谓殊途同归。
总结
本文介绍了多种方式计算两个日期之间差量。当然也可以通过第三方时间库实现,如JodaTime、Date4J,读者可以自己扩展。