Checking if Two Java Dates are On the Same Day – 检查两个Java日期是否在同一天

最后修改: 2019年 11月 30日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this quick tutorial, we’ll learn about several different ways to check if two java.util.Date objects have the same day.

在这个快速教程中,我们将学习几种不同的方法来检查两个java.util.Date对象的日期是否相同

We’ll start by considering solutions using core Java – namely, Java 8 features – before looking at a couple of pre-Java 8 alternatives.

我们将首先考虑使用核心Java的解决方案–即Java 8的功能–然后再看看几个Java 8之前的替代品。

To finish, we’ll also look at some external libraries — Apache Commons Lang, Joda-Time, and Date4J.

最后,我们还将看看一些外部库–Apache Commons Lang, Joda-Time, 和 Date4J

2. Core Java

2.核心Java

The class Date represents a specific instant in time, with millisecond precision. To find out if two Date objects contain the same day, we need to check if the Year-Month-Day is the same for both objects and discard the time aspect.

Date类代表了一个特定的时间瞬间,精度为毫秒。为了找出两个Date对象是否包含相同的一天,我们需要检查两个对象的年月日是否相同,并抛弃时间方面的内容

2.1. Using LocalDate

2.1.使用LocalDate

With the new Date-Time API of Java 8, we can use the LocalDate object. This is an immutable object representing a date without a time.

通过新的Java 8的日期时间API,我们可以使用LocalDate对象。这是一个不可变的对象,代表一个没有时间的日期。

Let’s see how we can check if two Date objects have the same day using this class:

让我们看看如何使用这个类来检查两个Date对象是否具有相同的日期。

public static boolean isSameDay(Date date1, Date date2) {
    LocalDate localDate1 = date1.toInstant()
      .atZone(ZoneId.systemDefault())
      .toLocalDate();
    LocalDate localDate2 = date2.toInstant()
      .atZone(ZoneId.systemDefault())
      .toLocalDate();
    return localDate1.isEqual(localDate2);
}

In this example, we’ve converted both the Date objects to LocalDate using the default timezone. Once converted, we just need to check if the LocalDate objects are equal using the isEqual method.

在这个例子中,我们已经使用默认的时区将两个Date对象转换为LocalDate 。一旦转换完成,我们只需要使用isEqual方法检查LocalDate对象是否相等。

Consequently, using this approach, we’ll be able to determine if the two Date objects contain the same day.

因此,使用这种方法,我们将能够确定这两个Date对象是否包含同一个日期。

2.2. Using Instant

2.2.使用Instant

In the example above, we used Instant as an intermediate object when converting Date objects to LocalDate objects. Instant, introduced in Java 8, represents a specific point in time.

在上面的例子中,我们在将Date对象转换为LocalDate对象时使用了Instant作为中间对象。Instant,在Java 8中引入,代表一个特定的时间点

We can directly truncate the Instant objects to the DAYS unit, which sets the time field values to zero, and then we can compare them:

我们可以直接Instant对象截断为DAYS单位,将时间字段的值设为0,然后我们就可以进行比较。

public static boolean isSameDayUsingInstant(Date date1, Date date2) {
    Instant instant1 = date1.toInstant()
      .truncatedTo(ChronoUnit.DAYS);
    Instant instant2 = date2.toInstant()
      .truncatedTo(ChronoUnit.DAYS);
    return instant1.equals(instant2);
}

2.3. Using SimpleDateFormat

2.3.使用SimpleDateFormat

Since early versions of Java, we’ve been able to use the SimpleDateFormat class to convert between Date and String object representations. This class comes with support for conversion using many patterns. In our case, we will use the pattern “yyyyMMdd”.

从Java的早期版本开始,我们就可以使用SimpleDateFormat类来在DateString对象表示之间转换。这个类支持使用许多模式进行转换。在我们的案例中,我们将使用模式 “yyyyMMdd”

Using this, we’ll format the Date, convert it to a String object, and then compare them using the standard equals method:

利用这一点,我们将格式化Date,转换为String对象,然后使用标准的equals方法来比较它们。

public static boolean isSameDay(Date date1, Date date2) {
    SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
    return fmt.format(date1).equals(fmt.format(date2));
}

2.4. Using Calendar

2.4.使用Calendar

The Calendar class provides methods to get the values of different date-time units for a particular instant of time.

Calendar类提供了一些方法来获取某一特定瞬间的不同日期-时间单位的值。

Firstly, we need to create a Calendar instance and set the Calendar objects’ time using each of the provided dates. Then we can query and compare the Year-Month-Day attributes individually to figure out if the Date objects have the same day:

首先,我们需要创建一个Calendar实例,并使用每个提供的日期设置Calendar对象的时间。然后我们可以查询并单独比较年-月-日属性,以找出日期对象是否有相同的日期。

public static boolean isSameDay(Date date1, Date date2) {
    Calendar calendar1 = Calendar.getInstance();
    calendar1.setTime(date1);
    Calendar calendar2 = Calendar.getInstance();
    calendar2.setTime(date2);
    return calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR)
      && calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH)
      && calendar1.get(Calendar.DAY_OF_MONTH) == calendar2.get(Calendar.DAY_OF_MONTH);
}

3. External Libraries

3.外部图书馆

Now that we have a good understanding of how to compare Date objects using the new and old APIs offered by core Java, let’s take a look at some external libraries.

现在我们已经很好地理解了如何使用核心Java提供的新旧API来比较Date对象,让我们看看一些外部库。

3.1. Apache Commons Lang DateUtils

3.1.Apache Commons Lang DateUtils

The DateUtils class provides many useful utilities that make it easier to work with the legacy Calendar and Date objects.

DateUtils类提供了许多有用的工具,使其更容易处理传统的CalendarDate对象

The Apache Commons Lang artifact is available from Maven Central:

Apache Commons Lang工件可从Maven Central获得。

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

Then we can simply use the method isSameDay from DateUtils:

那么我们可以简单地使用DateUtils中的isSameDay方法。

DateUtils.isSameDay(date1, date2);

3.2. Joda-Time Library

3.2.Joda-时间库

An alternative to the core Java Date and Time library is Joda-Time. This widely used library serves an excellent substitute when working with Date and Time.

核心Java DateTime库的一个替代方案是Joda-Time这个被广泛使用的在处理日期和时间时起到了很好的替代作用

The artifact can be found on Maven Central:

该工件可以在Maven Central上找到。

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

In this library, org.joda.time.LocalDate represents a date without time. Hence, we can construct the LocalDate objects from the java.util.Date objects and then compare them:

在这个库中,org.joda.time.LocalDate代表一个没有时间的日期。因此,我们可以从java.util.Date对象中构造LocalDate对象,然后对它们进行比较。

public static boolean isSameDay(Date date1, Date date2) {
    org.joda.time.LocalDate localDate1 = new org.joda.time.LocalDate(date1);
    org.joda.time.LocalDate localDate2 = new org.joda.time.LocalDate(date2);
    return localDate1.equals(localDate2);
}

3.3. Date4J Library

3.3.Date4J库

Date4j also provides a straightforward and simple implementation that we can use.

Date4j也提供了一个直接而简单的实现,我们可以使用。

Likewise, it is also available from Maven Central:

同样,也可以从Maven Central获得。

<dependency>
    <groupId>com.darwinsys</groupId>
    <artifactId>hirondelle-date4j</artifactId>
    <version>1.5.1</version>
</dependency>

Using this library, we need to construct the DateTime object from a java.util.Date object. Then we can simply use the isSameDayAs method:

使用这个库,我们需要从一个java.util.Date对象中构建DateTime对象。然后我们可以简单地使用isSameDayAs方法

public static boolean isSameDay(Date date1, Date date2) {
    DateTime dateObject1 = DateTime.forInstant(date1.getTime(), TimeZone.getDefault());
    DateTime dateObject2 = DateTime.forInstant(date2.getTime(), TimeZone.getDefault());
    return dateObject1.isSameDayAs(dateObject2);
}

4. Conclusion

4.总结

In this quick tutorial, we’ve explored several ways of checking if two java.util.Date objects contain the same day.

在这个快速教程中,我们探讨了几种检查两个java.util.Date对象是否包含相同日期的方法。

As always, the full source code of the article is available over on GitHub.

一如既往,文章的完整源代码可在GitHub上获得over。