1. 概述
在这个简短教程中,我们将讲解如何在Java中获取给定月份的最后一天。
首先,我们将展示如何使用核心Java方法实现。然后,我们将通过Joda Time库来演示相同的目标。
2. Java 8 之前
在Java 8之前,Date
和Calendar
类是处理时间和日期的常用选项。
通常,Calendar
类提供了一套方法和常量,我们可以利用它们访问和操作诸如日期、月份和年份等时间信息。
让我们来看看如何使用它来获取特定月份的最后一天:
static int getLastDayOfMonthUsingCalendar(int month) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, month);
return cal.getActualMaximum(Calendar.DAY_OF_MONTH);
}
如图所示,我们通过Calendar.getInstance()
创建一个Calendar
对象。接着,我们将日历的月份设置为指定的值。此外,我们使用getActualMaximum()
方法和Calendar.DAY_OF_MONTH
字段来获取月份的最后一天。
现在,让我们添加一个测试用例来验证我们的方法:
@Test
void givenMonth_whenUsingCalendar_thenReturnLastDay() {
assertEquals(31, LastDayOfMonth.getLastDayOfMonthUsingCalendar(0));
assertEquals(30, LastDayOfMonth.getLastDayOfMonthUsingCalendar(3));
assertEquals(31, LastDayOfMonth.getLastDayOfMonthUsingCalendar(9));
}
这里需要注意的是,月份的值是基于零的。例如,一月的值为0,所以我们需要从想要的月份值中减去1。
3. Java 8 日期时间API
Java 8引入了许多新功能和改进。其中,我们有日期时间API。这个API是为了克服旧API(基于Date
和Calendar
类)的局限性而设计的。
接下来,我们将深入探讨新API为获取月份最后一天提供的选项。
3.1. 使用YearMonth
处理月份的一种常见方式是使用YearMonth
类。顾名思义,它表示一年中的某个月份。
这个类提供了atEndOfMonth()
方法,返回一个LocalDate
对象,表示给定月份的最后一天。
让我们实战演示一下:
static int getLastDayOfMonthUsingYearMonth(YearMonth date) {
return date.atEndOfMonth()
.getDayOfMonth();
}
简而言之,我们使用atEndOfMonth()
获取月份的最后一天,然后通过getDayOfMonth()
获取返回的LocalDate
对象的天数。
当然,我们也需要添加一个测试用例:
@Test
void givenMonth_whenUsingYearMonth_thenReturnLastDay() {
assertEquals(31, LastDayOfMonth.getLastDayOfMonthUsingYearMonth(YearMonth.of(2023, 1)));
assertEquals(30, LastDayOfMonth.getLastDayOfMonthUsingYearMonth(YearMonth.of(2023, 4)));
assertEquals(31, LastDayOfMonth.getLastDayOfMonthUsingYearMonth(YearMonth.of(2023, 10)));
}
3.2. 使用TemporalAdjusters
另一种解决方案是使用TemporalAdjusters
类。通常,这个类提供了一系列现成的静态方法,我们可以用来调整时间对象。
一起看看如何使用它来获取LocalDate
实例的最后一天:
static int getLastDayOfMonthUsingTemporalAdjusters(LocalDate date) {
return date.with(TemporalAdjusters.lastDayOfMonth())
.getDayOfMonth();
}
如上所示,类提供了调整器lastDayOfMonth()
。它返回一个新的日期,设为该月的最后一天。
此外,我们使用getDayOfMonth()
方法获取返回日期的天数。
接下来,我们将用一个测试用例确认我们的方法:
@Test
void givenMonth_whenUsingTemporalAdjusters_thenReturnLastDay() {
assertEquals(31, LastDayOfMonth.getLastDayOfMonthUsingTemporalAdjusters(LocalDate.of(2023, 1, 1)));
assertEquals(30, LastDayOfMonth.getLastDayOfMonthUsingTemporalAdjusters(LocalDate.of(2023, 4, 1)));
assertEquals(31, LastDayOfMonth.getLastDayOfMonthUsingTemporalAdjusters(LocalDate.of(2023, 10, 1)));
}
4. Joda Time库
另外,我们可以使用Joda Time库达成同样的目的。在Java 8之前,它是日期时间处理的事实标准。首先,我们需要在pom.xml
文件中添加Joda Time的依赖项:
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.12.5</version>
</dependency>
同样,Joda Time也提供了LocalDate
类来表示日期。它包括withMaximumValue()
方法,可以用来获取月份的最后一天。
让我们实际操作一下:
static int getLastDayOfMonthUsingJodaTime(org.joda.time.LocalDate date) {
return date.dayOfMonth()
.withMaximumValue()
.getDayOfMonth();
}
最后,我们再创建一个测试用例:
@Test
void givenMonth_whenUsingJodaTime_thenReturnLastDay() {
assertEquals(31, LastDayOfMonth.getLastDayOfMonthUsingJodaTime(org.joda.time.LocalDate.parse("2023-1-1")));
assertEquals(30, LastDayOfMonth.getLastDayOfMonthUsingJodaTime(org.joda.time.LocalDate.parse("2023-4-1")));
assertEquals(31, LastDayOfMonth.getLastDayOfMonthUsingJodaTime(org.joda.time.LocalDate.parse("2023-10-1")));
}
不出所料,测试成功通过。
5. 总结
在这篇文章中,我们探讨了在Java中获取给定月份最后一天的不同方法。过程中,我们解释了如何使用核心Java实现。然后,我们展示了如何使用第三方库,如Joda Time。
如往常一样,本文使用的代码可以在GitHub找到。