【问题标题】:Inclusive Date Range check in Joda Time包含日期范围检查在 Joda 时间
【发布时间】:2012-11-15 01:22:02
【问题描述】:

我正在使用 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,但没有找到任何相关信息。

【问题讨论】:

标签: java date datetime jodatime


【解决方案1】:

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

解决方法:用“not before”代替“after”,用“not after”代替“before”。

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

【讨论】:

    【解决方案2】:

    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 项目现在位于maintenance mode,团队建议迁移到java.time 类。见Tutorial by Oracle

    仅限日期

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

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

    该类提供了几种比较方法:abutscontainsenclosesequalsintersectionisBeforeisAfterisConnectedoverlaps、@987654@3和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 类。

    从您的LocalDate 开始,让该班级决定一天的第一时间。由于夏令时 (DST) 等异常情况,这一天总是从 00:00:00 开始。

    continent/region 的格式指定proper time zone name,例如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-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 ) ;
    

    半开

    定义时间跨度的最佳方法通常是半开放方法。这意味着开头是inclusive,而结尾是exclusive

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


    关于java.time

    java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

    Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

    要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

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

    从哪里获得 java.time 类?

    ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-23
      • 2017-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多