Joda Time中的包含日期范围检查

26

我正在使用 Joda Time 2.1 库。

我编写了一个方法来比较给定日期是否在日期范围内。我希望它包括开始日期和结束日期。我使用了 LocalDate,因为我只想考虑日期部分而不是时间部分。

以下是代码:

isDateBetweenRange(LocalDate start,LocalDate end,LocalDate target){

       System.out.println("Start Date : "
              +start.toDateTimeAtStartOfDay(DateTimeZone.forID("EST"));

       System.out.println("Target Date : "
              +targettoDateTimeAtStartOfDay(DateTimeZone.forID("EST"));

       System.out.println("End Date : "
              +end.toDateTimeAtStartOfDay(DateTimeZone.forID("EST"));

       System.out.println(target.isAfter(start));

       System.out.println(target.isBefore(end));
}

以上方法的输出为:

Start Date: 2012-11-20T00:00:00.000-05:00
Target Date: 2012-11-20T00:00:00.000-05:00
End Date : 2012-11-21T00:00:00.000-05:00
target.isAfter(start) : false
target.isBefore(end) : true

我的问题是,即使target日期和start日期具有相同的值,target.isAfter(start)也为false。

我希望target >= start,但这里仅考虑target > start
我希望它包含相等的情况。

这是否意味着isAfter方法只找到独占匹配?

我已经查看了Joda Time的javadoc,但没有找到任何相关信息。


请在类似线程中检查我的答案,涉及本地日期的区间:https://dev59.com/9G855IYBdhLWcg3wXS8I#14998753 - Dmitry Serdiuk
2个回答

65

是的,isAfter是排除的,否则它可能应该被命名为isEqualOrAfter或类似的名称。

解决方案:使用“不早于”代替“之后”,使用“不晚于”代替“之前”。

boolean isBetweenInclusive(LocalDate start, LocalDate end, LocalDate target) {
    return !target.isBefore(start) && !target.isAfter(end);
}

1

简而言之

Joda-Time已被java.time类和ThreeTen-Extra项目所取代。

LocalDateRangeInterval类表示时间跨度使用半开放定义。因此,询问开始是否包含返回true

LocalDateRange.of(                     // `org.threeten.extra.LocalDateRange` class represents a pair of `LocalDate` objects as a date range.
    LocalDate.of( 2018, 8 , 2 ) ,      // `java.time.LocalDate` class represents a date-only value, without time-of-day and without time zone.
    LocalDate.of( 2018 , 8 , 20 ) 
)                                      // Returns a `LocalDateRange` object.
.contains(
    LocalDate.now()                    // Capture the current date as seen in the wall-clock time used by the people of the JVM’s current default time zone.
)

true

java.time

FYI,Joda-Time 项目现在处于维护模式,团队建议迁移到java.time类。请参见Oracle的教程

仅日期

显然,您可能关心日期而不是时间。如果是这样,请使用LocalDate类。

如果您想管理日期范围,请将 ThreeTen-Extra 库添加到您的项目中。这将使您可以访问 LocalDateRange 类。

该类提供了几种比较方法:abutscontainsenclosesequalsintersectionisBeforeisAfterisConnectedoverlapsspanunion

LocalDateRange r = 
    LocalDateRange.of( 
        LocalDate.of( 2018, 8 , 2 ) , 
        LocalDate.of( 2018 , 8 , 20 ) 
    ) 
;

LocalDate target = LocalDate.now( ZoneId.of( "Africa/Tunis" ) ) ;  // Capture the current date as seen in the wall-clock time used by the people of a particular time zone.
boolean contains = r.contains( target ) ;

日期和时间

如果您关心特定时区的日期和时间,请使用 ZonedDateTime 类。

从您的 LocalDate 开始,让该类确定一天的第一个时刻。由于诸如夏令时(DST)等异常情况,一天并不总是从00:00:00开始。

continent/region 的格式指定适当的时区名称,例如America/MontrealAfrica/CasablancaPacific/Auckland。永远不要使用三到四个字母的缩写,例如ESTIST,因为它们不是真正的时区,没有标准化,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "America/Montreal" ) ;  // Or "America/New_York", etc.
ZonedDateTime zdtStart = LocalDate.of( 2018, 8 , 2 ).atStartOfDay( z ) ;
ZonedDateTime zdtStop = LocalDate.of( 2018, 8 , 20 ).atStartOfDay( z ) ;
ZonedDateTime zdtTarget = ZonedDateTime.now( z ) ;

ThreeTen-Extra中的Interval表示一个范围。这个类表示一对Instant对象。一个Instant是UTC时间中的一个瞬间,总是在UTC时间中。我们可以通过简单地提取Instant来轻松地从我们的时区时刻调整到UTC。同一时刻,在时间线上的同一点,不同的挂钟时间。
Instant instantStart = zdtStart.toInstant() ;
Instant instantStop = zdtStop.toInstant() ;
Instant instantTarget = zdtTarget.toInstant() ;

Interval interval = Interval.of( instantStart , intervalStop ) ;
boolean contains = interval.contains( instantTarget ) ;

半开区间

定义时间跨度的最佳方法通常是采用半开区间方法。这意味着开始时间是包含的,而结束时间是不包含的。

上面看到的ThreeTen-Extra范围类(LocalDateRangeInterval)中的比较都使用半开区间方法。因此,询问起始日期或起始时刻是否包含在范围内将得到一个true


关于 java.time

java.time 框架已经内置于 Java 8 及以后的版本中。这些类替代了旧的、麻烦的遗留日期时间类,如 java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在处于维护模式,建议迁移到java.time类。

了解更多信息,请参阅Oracle教程。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC驱动程序。无需字符串,无需java.sql.*类。

如何获取java.time类?

ThreeTen-Extra 项目扩展了 java.time 的附加类。该项目是 java.time 可能未来添加的一个试验场。您可能会在此处找到一些有用的类,例如 Interval, YearWeek, YearQuarter, 和 更多


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接