java Joda 时间中的包含日期范围检查
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13583944/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Inclusive Date Range check in Joda Time
提问by Abubakkar
I am using Joda Time 2.1 library.
我正在使用 Joda Time 2.1 库。
I have written a method to compare if a given date is between a date range of not. I want it to be inclusive to the start date and end date.I have used LocalDate
as I don't want to consider the time part only date part.
我编写了一种方法来比较给定日期是否在日期范围内。我希望它包含开始日期和结束日期。LocalDate
我已经使用过,因为我不想只考虑时间部分的日期部分。
Below is the code for it.
下面是它的代码。
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));
}
The output of above method is :
上述方法的输出是:
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
My problem is target.isAfter(start)
is false even if the target
date and start
are having the same values.
我的问题是target.isAfter(start)
即使target
日期和start
具有相同的值也是假的。
I want that target >= start
but here it considers only target > start
.
I want it inclusive.
我想要那个,target >= start
但在这里它只考虑target > start
.
我想要包容。
Does it mean that isAfter
method finds a match exclusively ?
这是否意味着该isAfter
方法只能找到匹配项?
I have gone through the javadoc for Joda Time, but didn't found anything about it.
我已经浏览了 Joda Time 的 javadoc,但没有找到任何关于它的信息。
回答by Jesper
Yes, isAfter
is exclusive, otherwise it should probably have been named isEqualOrAfter
or something similar.
是的,isAfter
是排他性的,否则它可能应该被命名isEqualOrAfter
或类似的东西。
Solution: Use "not before" instead of "after", and "not after" instead of "before".
解决方法:用“not before”代替“after”,用“not after”代替“before”。
boolean isBetweenInclusive(LocalDate start, LocalDate end, LocalDate target) {
return !target.isBefore(start) && !target.isAfter(end);
}
回答by Basil Bourque
tl;dr
tl;博士
Joda-Time has been supplanted by the java.timeclasses and the ThreeTen-Extraproject.
Joda-Time 已被java.time类和ThreeTen-Extra项目取代。
The LocalDateRange
and Interval
classes representing a span-of-time use the Half-Open definition. So, asking if the beginning is contained returns true
.
表示时间跨度的LocalDateRange
和Interval
类使用半开放定义。因此,询问开头是否包含返回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, the Joda-Timeproject is now in maintenance mode, with the team advising migration to the java.timeclasses. See Tutorial by Oracle.
仅供参考,Joda-Time项目现在处于维护模式,团队建议迁移到java.time类。请参阅Oracle 教程。
Date-only
仅限日期
Apparently you may care about the date and not the time-of-day. If so, use LocalDate
class.
显然,您可能关心日期而不是一天中的时间。如果是这样,请使用LocalDate
类。
For managing a date range, add the ThreeTen-Extralibrary to your project. This gives you access to the LocalDateRange
class.
要管理日期范围,请将ThreeTen-Extra库添加到您的项目中。这使您可以访问LocalDateRange
该类。
That class offers several methods for comparison: abuts
, contains
, encloses
, equals
, intersection
, isBefore
, isAfter
, isConnected
, overlaps
, span
, and union
.
这个类提供了几种比较:abuts
,contains
,encloses
,equals
,intersection
,isBefore
,isAfter
,isConnected
,overlaps
,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 ) ;
Date-time
约会时间
If you care about the date and the time-of-day in a particular time zone, use ZonedDateTime
class.
如果您关心特定时区中的日期和时间,请使用ZonedDateTime
class。
Start with your LocalDate
, and let that class determine the first moment of the day. The day does notalways start at 00:00:00 because of anomalies such as Daylight Saving Time (DST).
从你的 开始LocalDate
,让那个班级决定一天中的第一个时刻。这一天也不能总是从00:00:00因为异常如夏令时(DST) 。
Specify a proper time zone namein the format of continent/region
, such as America/Montreal
, Africa/Casablanca
, or Pacific/Auckland
. Never use the 3-4 letter abbreviation such as EST
or IST
as they are nottrue time zones, not standardized, and not even unique(!).
以、、 或等格式指定正确的时区名称。永远不要使用 3-4 个字母的缩写,例如或因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。continent/region
America/Montreal
Africa/Casablanca
Pacific/Auckland
EST
IST
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 ) ;
Represent a range with the Interval
from ThreeTen-Extra. This class represents a pair of Instant
objects. An Instant
is a moment in UTC, always in UTC. We can easily adjust from our zoned moment to UTC by simply extracting an Instant
. Same moment, same point on the timeline, different wall-clock time.
用Interval
from ThreeTen-Extra表示一个范围。这个类代表一对Instant
对象。AnInstant
是 UTC 中的一个时刻,始终是 UTC。我们可以通过简单地提取一个Instant
. 同一时刻,时间线上的同一点,不同的挂钟时间。
Instant instantStart = zdtStart.toInstant() ;
Instant instantStop = zdtStop.toInstant() ;
Instant instantTarget = zdtTarget.toInstant() ;
Interval interval = Interval.of( instantStart , intervalStop ) ;
boolean contains = interval.contains( instantTarget ) ;
Half-Open
半开
The best approach to defining a span-of-time is generally the Half-Openapproach. This means the beginning is inclusivewhile the ending is exclusive.
定义时间跨度的最佳方法通常是半开放方法。这意味着开头是包容性的,而结尾是排斥性的。
The comparisons in the ThreeTen-Extra
range classes seen above (LocalDateRange
& Interval
) both use Half-Open approach. So asking if the starting date or starting moment is contained in the range results in a true
.
ThreeTen-Extra
上面看到的范围类 ( LocalDateRange
& Interval
) 中的比较都使用半开方法。因此,询问开始日期或开始时刻是否包含在范围内会导致true
.
About java.time
关于java.time
The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
该java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date
, Calendar
, & SimpleDateFormat
。
The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310。
You may exchange java.timeobjects directly with your database. Use a JDBC drivercompliant with JDBC 4.2or later. No need for strings, no need for java.sql.*
classes.
您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*
Where to obtain the java.time classes?
从哪里获得 java.time 类?
- Java SE 8, Java SE 9, Java SE 10, and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6and Java SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- Later versions of Android bundle implementations of the java.timeclasses.
- For earlier Android (<26), the ThreeTenABPproject adapts ThreeTen-Backport(mentioned above). See How to use ThreeTenABP….
- Java SE 8、Java SE 9、Java SE 10及更高版本
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9 添加了一些小功能和修复。
- Java SE 6和Java SE 7
- 多的java.time功能后移植到Java 6和7在ThreeTen-反向移植。
- 安卓
- 更高版本的 Android 捆绑实现java.time类。
- 对于早期的 Android(<26),ThreeTenABP项目采用了ThreeTen-Backport(上面提到过)。请参阅如何使用ThreeTenABP ...。
The ThreeTen-Extraproject 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.
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。