1. 概述

在这个简短教程中,我们将探讨在Java中获取昨天日期的不同方法。

首先,我们将解释如何使用核心Java来实现。然后,我们将展示如何利用Joda-Time和Apache Commons Lang等外部库来解决主要问题。

2. Java 8 之前

在Java 8之前,我们通常会使用DateCalendar类来处理和操作日期/时间信息。接下来,让我们看看如何使用这两个类获取昨天的日期。

2.1. 使用Date

Date类表示时间的特定瞬间。它提供了一组方法来操作和获取日期信息。然而,需要注意的是,这个类已经过时并被标记为废弃

让我们实际操作一下:

@Test
void givenDate_whenUsingDateClass_thenReturnYesterday() {
    Date date = new Date(2023, Calendar.DECEMBER, 20);
    Date yesterdayDate = new Date(date.getTime() - 24 * 60 * 60 * 1000);
    Date expectedYesterdayDate = new Date(2023, Calendar.DECEMBER, 19);

    assertEquals(expectedYesterdayDate, yesterdayDate);
}

如图所示,我们使用getTime()方法获取给定日期的毫秒数。然后,我们减去一天,即24 * 60 * 60 * 1000毫秒

2.2. 使用Calendar

如果想使用旧API,Calendar是另一个可考虑的选项。这个类提供了一系列管理时间数据的方法,如天数和月份。

例如,我们可以使用add()方法添加一定数量的天数。由于我们想要获取昨天的日期,我们需要指定值为-1。

以下是实际操作的示例:

@Test
void givenDate_whenUsingCalendarClass_thenReturnYesterday() {
    Calendar date = new GregorianCalendar(2023, Calendar.APRIL, 20, 4, 0);
    date.add(Calendar.DATE, -1);
    Calendar expectedYesterdayDate = new GregorianCalendar(2023, Calendar.APRIL, 19, 4, 0);

    assertEquals(expectedYesterdayDate, date);
}

正如预期,测试成功通过。

3. Java 8 日期时间API

Java 8因其新的日期时间特性而备受赞誉。这个API提供了大量现成的类和方法,以更简洁、更人性化的形式进行日期和时间计算。现在,让我们仔细看看如何使用新日期时间API获取昨天的日期。

3.1. 使用LocalDate

一个简单的解决方案是使用LocalDate类。它提供了minusDays()方法,可以从给定日期中减去特定数量的天数。在这种情况下,我们需要减去恰好一天。

现在,让我们用一个测试用例来演示LocalDate.minusDays()的使用:

@Test
void givenDate_whenUsingLocalDateClass_thenReturnYesterday() {
    LocalDate localDate = LocalDate.of(2023, 12, 20);
    LocalDate yesterdayDate = localDate.minusDays(1);
    LocalDate expectedYesterdayDate = LocalDate.of(2023, 12, 19);

    assertEquals(expectedYesterdayDate, yesterdayDate);
}

如上所述,minusDays(1)返回一个新的LocalDate对象,表示昨天的日期。

3.2. 使用Instant

另一种解决方案是使用Instant类。顾名思义,它表示时间线上特定的时间点。通常,Instant类带有minus()方法,我们可以用来减去特定数量的毫秒

下面是一个实际示例,说明如何使用它获取昨天的日期:

@Test
void givenDate_whenUsingInstantClass_thenReturnYesterday() {
    Instant date = Instant.parse("2023-10-25");
    Instant yesterdayDate = date.minus(24 * 60 * 60 * 1000);
    Instant expectedYesterdayDate = Instant.parse("2023-10-24");

    assertEquals(expectedYesterdayDate, yesterdayDate);
}

正如前面提到的,24 * 60 * 60 * 1000代表一天的毫秒数。在这里,我们从给定日期中减去一天。

4. 使用Joda-Time

同样,我们也可以使用Joda-Time API来回答核心问题。首先,我们需要将其Maven依赖项添加到pom.xml文件中:

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

Joda-Time是在Java 8发布之前日期和时间处理的事实标准。它提供了自己的LocalDate类版本。让我们实践一下:

@Test
void givenDate_whenUsingJodaTimeLocalDateClass_thenReturnYesterday() {
    org.joda.time.LocalDate localDate = new org.joda.time.LocalDate(2023, 12, 20);
    org.joda.time.LocalDate yesterdayDate = localDate.minusDays(1);
    org.joda.time.LocalDate expectedYesterdayDate = new org.joda.time.LocalDate(2023, 12, 19);

    assertEquals(expectedYesterdayDate, yesterdayDate);
}

简而言之,这个类提供了与名称相符的minusDays()方法,我们可以用它来减去特定数量的天数

5. 使用Apache Commons Lang3

另一方面,我们可以选择使用Apache Commons Lang3库。如常,我们首先需要添加Maven依赖才能开始使用:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>

现在,让我们演示如何使用这个库获取昨天的日期:

@Test
void givenDate_whenUsingApacheCommonsLangDateUtils_thenReturnYesterday() {
    Date date = new GregorianCalendar(2023, Calendar.MAY, 16, 4, 0).getTime();
    Date yesterdayDate = DateUtils.addDays(date, -1);
    Date expectedYesterdayDate = new GregorianCalendar(2023, Calendar.MAY, 15, 4, 0).getTime();

    assertEquals(expectedYesterdayDate, yesterdayDate);
}

Apache Commons Lang3库提供了DateUtils类进行日期时间操作。这个工具类提供了addDays()方法,用于添加天数,我们的案例中是-1天

请注意,该方法返回一个新的Date对象,原始给定的日期保持不变。

6. 总结

在这篇短文中,我们详细解释了如何在Java中获取昨天的日期。在整个过程中,我们展示了如何使用核心Java类。然后,我们展示了如何使用外部库,如Apache Commons Lang3和Joda-Time。

如往常一样,本文中的代码可以在GitHub上找到。