我正在使用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)
日期和target
具有相同的值,我的问题仍为start
。
我想要target >= start
,但这里只考虑target > start
我希望它具有包容性。
这是否意味着isAfter
方法只能找到匹配项?
我已经浏览了Joda Time的javadoc,但没有发现任何相关信息。
答案 0 :(得分:52)
是的,isAfter
是独占的,否则它应该被命名为isEqualOrAfter
或类似名称。
解决方案:使用“not before”而不是“after”,“not after”而不是“before”。
boolean isBetweenInclusive(LocalDate start, LocalDate end, LocalDate target) {
return !target.isBefore(start) && !target.isAfter(end);
}
答案 1 :(得分:1)
Joda-Time已被 java.time 类和 ThreeTen-Extra 项目取代。
表示时间跨度的LocalDateRange
和Interval
类使用Half-Open定义。因此,询问是否包含开头将返回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
仅供参考,Joda-Time项目现在位于maintenance mode中,团队建议迁移到java.time类。参见Tutorial by Oracle。
显然,您可能会关心日期而不是时间。如果是这样,请使用LocalDate
类。
要管理日期范围,请将ThreeTen-Extra库添加到项目中。这使您可以访问LocalDateRange
类。
该类提供了几种比较方法:abuts
,contains
,encloses
,equals
,intersection
,isBefore
,{{1 }},isAfter
,overlaps
,isConnected
和span
。
union
如果您关心特定时区中的日期和时间,请使用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
开始,让该课程确定一天的第一时刻。由于诸如夏令时(DST)之类的异常,并非一天总是从00:00:00开始。
以LocalDate
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或continent/region
。切勿使用3-4个字母的缩写,例如Pacific/Auckland
或EST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
IST
用 ThreeTen-Extra 中的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 ) ;
代表一个范围。此类表示一对Interval
对象。 Instant
是UTC中的时刻,始终是UTC中的时刻。只需提取Instant
,我们就可以轻松地将区域时刻调整为UTC。同一时刻,时间轴上的同一点,不同的时钟时间。
Instant
定义时间跨度的最佳方法通常是 Half-Open 方法。这意味着开始是包含,而结束是包含。
以上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
中看到的LocalDateRange
范围类中的比较都使用半开方法。因此,询问范围中是否包含开始日期或开始时间会导致Interval
。
java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和SimpleDateFormat
。
目前位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要true
类。
在哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如Interval
,YearWeek
,YearQuarter
和more。