开发过程中,经常需要某几天前或者某几天后的一个时间,此时,就需要用到对时间的加减运算。
Calendar
Java8 之前,时常使用 Calendar 操作日期。
private static void calendarCalc(){
Calendar calendar = Calendar.getInstance();
System.out.println("初始时间 " + calendar.getTime());
calendar.add(Calendar.DATE, 3);
System.out.println("加3天后 " + calendar.getTime());
calendar.add(Calendar.DATE, -3);
System.out.println("减3天后 " + calendar.getTime());
calendar.add(Calendar.MONTH, 2);
System.out.println("加2个月 " + calendar.getTime());
}
这里对某个时间加 3 天,使用到 add() 方法。其中第一个参数可以控制增加的级别(天、月),第二个参数可以控制增加(正数)还是减少(负数)。
初始时间 Sun Apr 03 21:58:04 CST 2022
加3天后 Wed Apr 06 21:58:04 CST 2022
减3天后 Sun Apr 03 21:58:04 CST 2022
加2个月 Fri Jun 03 21:58:04 CST 2022
加3天后 Wed Apr 06 21:58:04 CST 2022
减3天后 Sun Apr 03 21:58:04 CST 2022
加2个月 Fri Jun 03 21:58:04 CST 2022
Calendar 的 add()
方法直接操作传入的时间对象,该方法没有返回,使用 Calendar 时我们应该小心,因为它们有一些设计缺陷并且不是线程安全的。
LocalDateTime
Java 8 中引入的 Date/Time API 是目前最流行的日期和时间计算类。
使用 java.util.LocalDateTime
来计算日期:
private static void localDateCalc(){
LocalDateTime dateTime = LocalDateTime.now();
LocalDateTime minus5Days = dateTime.minus(5, ChronoUnit.DAYS);
LocalDateTime minus2Days = dateTime.minusDays(2);
LocalDateTime plus2Hours = dateTime.plusHours(2);
LocalDateTime plusMonth = dateTime.plus(1, ChronoUnit.MONTHS);
System.out.println("初始时间 " + dateTime);
System.out.println(" 5天前 " + minus5Days);
System.out.println(" 2天前 " + minus2Days);
System.out.println("加2小时 " + plus2Hours);
System.out.println("1个月后 " + plusMonth);
System.out.println("初始时间 " + dateTime);
}
LocalDateTime 的 API 更丰富,提供了 minus()
与 plus()
方法,可以通过第二个参数控制计算的级别(分、时、天、月),也有单独的 minusDays / plusHours 等方法来直接操作 年月日时分秒。
这些方法每次的返回都是一个新的时间对象,无论我们如何修改时间,原始的时间始终不变。
初始时间 2022-04-03T22:14:18.306
5天前 2022-03-29T22:14:18.306
2天前 2022-04-01T22:14:18.306
加2小时 2022-04-04T00:14:18.306
1个月后 2022-05-03T22:14:18.306
初始时间 2022-04-03T22:14:18.306
5天前 2022-03-29T22:14:18.306
2天前 2022-04-01T22:14:18.306
加2小时 2022-04-04T00:14:18.306
1个月后 2022-05-03T22:14:18.306
初始时间 2022-04-03T22:14:18.306
Joda-Time
我们可以使用 Joda-Time 作为 Java 初始日期和时间处理解决方案的更好替代方案。该库提供了更直观的 API、多个日历系统、线程安全和不可变对象。
为了使用Joda-Time,我们需要将它作为依赖项包含在pom.xml文件中:
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.14</version>
</dependency>
让我们从 Joda-Time 的DateTime对象中计算时间:
private static void jodaTimeCalc(){
DateTime dateTime = new DateTime(2022,4,3,22,25,13);
DateTime minus5Days = dateTime.minus(Period.days(5));
DateTime minus2Days = dateTime.minusDays(2);
DateTime plus2Hours = dateTime.plus(Duration.standardHours(2));
DateTime plusMonth = dateTime.plusMonths(1);
System.out.println("初始时间 " + dateTime);
System.out.println(" 5天前 " + minus5Days);
System.out.println(" 2天前 " + minus2Days);
System.out.println("加2小时 " + plus2Hours);
System.out.println("1个月后 " + plusMonth);
System.out.println("初始时间 " + dateTime);
}
初始时间 2022-04-03T22:25:13.000+08:00
5天前 2022-03-29T22:25:13.000+08:00
2天前 2022-04-01T22:25:13.000+08:00
加2小时 2022-04-04T00:25:13.000+08:00
1个月后 2022-05-03T22:25:13.000+08:00
初始时间 2022-04-03T22:25:13.000+08:00
5天前 2022-03-29T22:25:13.000+08:00
2天前 2022-04-01T22:25:13.000+08:00
加2小时 2022-04-04T00:25:13.000+08:00
1个月后 2022-05-03T22:25:13.000+08:00
初始时间 2022-04-03T22:25:13.000+08:00
Joda-Time 是遗留代码的一个很好的解决方案。不过,该项目的作者建议开发者将代码迁移到 Java 8 的 Date/Time API。