如何比较 Android 中的两个日期范围?

How to compare two date ranges in Android?

我目前正在尝试弄清楚如何使用 java 中的日历对象比较两个日期范围。

例如,如果给定的前两个日期是2021-7-1 and 2021-7-8,给定的后两个日期是2021-7-8 and 2021-7-10,它应该return false,因为给定的前两个日期范围日期和后两个给定日期在 2021-7-8.

处被覆盖

是否有可能使用 Calendar 和 Date 对象解决这个问题?

tl;博士

LocalDateRange a = LocalDateRange.ofClosed(
    LocalDate.parse( "2021-07-01" ) ,
    LocalDate.parse( "2021-07-08" )
)
.abuts(                                            // Or .overlaps or .isConnected
    LocalDateRange b = LocalDateRange.ofClosed(
        LocalDate.parse( "2021-07-08" ) ,
        LocalDate.parse( "2021-07-10" )
    )
)

避免遗留日期时间 classes

using Calendar object

切勿使用 CalendarDate。这些可怕的 classes 在几年前被 JSR 310 中定义的 java.time classes 所取代。

日期范围

if the first two given dates are 2021-7-1 and 2021-7-8 and the second two given dates are 2021-7-8 and 2021-7-10, it should return false because the date ranges of the first two given dates and the second two given dates are overwritten at 2021-7-8.

您想比较两个日期范围。

LocalDate

在现代 Java 中,我们使用 LocalDate 来表示没有时间和时区上下文或与 UTC 的偏移量的日期。

org.threeten.extra.LocalDateRange

要使用日期范围(一对 LocalDate 对象),我建议您添加 ThreeTen-Extra library to your project, free-of-cost and open-source. This library includes the LocalDateRange class,正是您所需要的。

半开跨度

您应该知道,在日期时间处理中,将时间跨度定义为半开通常是有意义的,其中开始是包含而结束是独家。因此,一整天从一天的第一刻开始,运行 直到但不包括 下一个 天的第一刻。

在您的情况下,您的第一个范围在 8 号结束,第二个范围在 8 号开始。根据半开规则,这两个范围将 abut rather than overlap.

LocalDateRange x = LocalDateRange.of(
        LocalDate.parse( "2021-07-01" ) ,
        LocalDate.parse( "2021-07-08" )
);
LocalDateRange y = LocalDateRange.of(
        LocalDate.parse( "2021-07-08" ) ,
        LocalDate.parse( "2021-07-10" )
);

boolean abuts = x.abuts( y );
boolean overlaps = x.overlaps( y );

当运行.

abuts = true

overlaps = false

我相信持续使用半开会使您的代码更易于阅读和推理,并且不太可能因疏忽而出错。

全封闭跨度

但是,如果您坚持完全封闭的方法,LocalDateRange class 可以让您以这种方式工作。使用 LocalDateRange.ofClosed rather than LocalDateRange.of.

LocalDateRange a = LocalDateRange.ofClosed(
        LocalDate.parse( "2021-07-01" ) ,
        LocalDate.parse( "2021-07-08" )
);
LocalDateRange b = LocalDateRange.ofClosed(
        LocalDate.parse( "2021-07-08" ) ,
        LocalDate.parse( "2021-07-10" )
);

boolean abuts = a.abuts( b );
boolean overlaps = a.overlaps( b );

当运行.

abuts = false

overlaps = true

使用全封闭方法,您的两个范围重叠而不是邻接,这与我们在前面的示例代码中看到的相反。

重叠邻接

注意 isConnected 方法,相当于 (overlaps(other) || abuts(other))LocalDateRange class 也提供其他比较方法。


关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

您可以直接与数据库交换 java.time 对象。使用 JDBC driver compliant with JDBC 4.2 或更高版本。不需要字符串,不需要 java.sql.* classes。 Hibernate 5 和 JPA 2.2 支持 java.time.

从哪里获得 java.time classes?

ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.