在Joda Time中查看包含日期范围

我正在使用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.isAfter(start)为false,即使target日期和start具有相同的值。

我希望target >= start但在这里它只考虑target > start
我希望它具有包容性。

这是否意味着isAfter方法专门找到匹配?

我已经浏览了Joda Time的javadoc,但没有找到任何关于它的内容。

是的, isAfter是独占的,否则它应该被命名为isEqualOrAfter或类似的东西。

解决方案:使用“not before”而不是“after”,“not after”而不是“before”。

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

TL;博士

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. ) 

真正

java.time

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

日期,只

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

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

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

 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)等exception,这一天并不总是从00:00:00开始。

continent/region的格式指定适当的时区名称 ,例如America/MontrealAfrica/CasablancaPacific/Auckland 。 切勿使用3-4字母缩写,例如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-ExtraInterval表示范围。 此类表示一对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类?

  • Java SE 8Java SE 9Java SE 10及更高版本
    • 内置。
    • 带有捆绑实现的标准Java API的一部分。
    • Java 9增加了一些小function和修复。
  • Java SE 6Java SE 7
    • 许多java.timefunction都被反向移植到ThreeTen-Backport中的 Java 6和7。
  • Android的
    • 更高版本的Android捆绑java.time类的实现。
    • 对于早期的Android(<26), ThreeTenABP项目采用ThreeTen-Backport (如上所述)。 请参见如何使用ThreeTenABP ….

ThreeTen-Extra项目使用其他类扩展了java.time。 该项目是未来可能添加到java.time的试验场。 您可以在这里找到一些有用的课程,如IntervalYearWeekYearQuarter等。