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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 13:18:26  来源:igfitidea点击:

Inclusive Date Range check in Joda Time

javadatedatetimejodatime

提问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 LocalDateas 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 targetdate and startare having the same values.

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

I want that target >= startbut here it considers only target > start.
I want it inclusive.

我想要那个,target >= start但在这里它只考虑target > start.
我想要包容。

Does it mean that isAftermethod 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, isAfteris exclusive, otherwise it should probably have been named isEqualOrAfteror 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 LocalDateRangeand Intervalclasses representing a span-of-time use the Half-Open definition. So, asking if the beginning is contained returns true.

表示时间跨度的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, 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 LocalDateclass.

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

For managing a date range, add the ThreeTen-Extralibrary to your project. This gives you access to the LocalDateRangeclass.

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

That class offers several methods for comparison: abuts, contains, encloses, equals, intersection, isBefore, isAfter, isConnected, overlaps, span, and union.

这个类提供了几种比较:abutscontainsenclosesequalsintersectionisBeforeisAfterisConnectedoverlapsspan,和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 ZonedDateTimeclass.

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

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 ESTor ISTas they are nottrue time zones, not standardized, and not even unique(!).

以、、 或等格式指定正确的时区名称。永远不要使用 3-4 个字母的缩写,例如或因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。continent/regionAmerica/MontrealAfrica/CasablancaPacific/AucklandESTIST

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 Intervalfrom ThreeTen-Extra. This class represents a pair of Instantobjects. An Instantis 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.

Intervalfrom 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-Extrarange 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 类?

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 的试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多