1. 概述

在这个教程中,我们将学习在Java中从日期对象中减去天数的各种方法。首先,我们将使用Java 8引入的日期时间API。之后,我们将通过java.util包中的类来实现,最后借助Joda-Time库来完成相同的任务。

2. java.time.LocalDateTime

Java 8中引入的日期/时间API目前是进行日期和时间计算的最佳选择。

让我们看看如何从Java 8的java.time.LocalDateTime对象中减去天数:

@Test
public void givenLocalDate_whenSubtractingFiveDays_dateIsChangedCorrectly() {
    LocalDateTime localDateTime = LocalDateTime.of(2022, 4, 20, 0, 0);

    localDateTime = localDateTime.minusDays(5);

    assertEquals(15, localDateTime.getDayOfMonth());
    assertEquals(4, localDateTime.getMonthValue());
    assertEquals(2022, localDateTime.getYear());
}

3. java.util.Calendar

在Java 8之前,java.util.Datejava.util.Calendar是进行日期操作的常用实用类。

使用java.util.Calendar从日期中减去五天:

@Test
public void givenCalendarDate_whenSubtractingFiveDays_dateIsChangedCorrectly() {
    Calendar calendar = Calendar.getInstance();
    calendar.set(2022, Calendar.APRIL, 20);

    calendar.add(Calendar.DATE, -5);

    assertEquals(15, calendar.get(Calendar.DAY_OF_MONTH));
    assertEquals(Calendar.APRIL, calendar.get(Calendar.MONTH));
    assertEquals(2022, calendar.get(Calendar.YEAR));
}

在使用它们时需要小心,因为它们存在一些设计缺陷且不具备线程安全。

有关与旧代码交互以及两个API之间的差异的更多信息,请参阅关于迁移到新的Java 8日期时间API的文章。

4. Joda-Time

我们可以将Joda-Time作为Java初始日期和时间处理解决方案的一个更好替代。该库提供了更直观的API、多个历法系统、线程安全性和不可变对象。

为了使用Joda-Time,我们需要将其作为依赖项添加到pom.xml文件中:

<dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
    <version>2.12.5</version>
</dependency>

现在,让我们从Joda-Time的DateTime对象中减去五天:

@Test
public void givenJodaDateTime_whenSubtractingFiveDays_dateIsChangedCorrectly() {
    DateTime dateTime = new DateTime(2022, 4, 20, 12, 0, 0);

    dateTime = dateTime.minusDays(5);

    assertEquals(15, dateTime.getDayOfMonth());
    assertEquals(4, dateTime.getMonthOfYear());
    assertEquals(2022, dateTime.getYear());
}

Joda-Time对于遗留代码是一个好的解决方案。然而,该项目已被官方宣布“完成”,并且建议由库作者推荐迁移到Java 8的日期/时间API。

5. 总结

在这篇简短的文章中,我们探讨了从日期对象中减去天数的几种方法。我们通过java.time.LocalDateTime和Java 8之前的解决方案(java.util.Calendar和Joda-Time库)实现了这一目标。

如往常一样,源代码可在GitHub上找到。