Inclusive Date Range check in Joda Time

后端 未结 2 774
孤街浪徒
孤街浪徒 2021-02-04 00:24

I am using Joda Time 2.1 library.

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

相关标签:
2条回答
  • 2021-02-04 00:38

    tl;dr

    Joda-Time has been supplanted by the java.time classes and the ThreeTen-Extra project.

    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.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-Time project is now in maintenance mode, with the team advising migration to the java.time classes. See Tutorial by Oracle.

    Date-only

    Apparently you may care about the date and not the time-of-day. If so, use LocalDate class.

    For managing a date range, add the ThreeTen-Extra library to your project. This gives you access to the LocalDateRange class.

    That class offers several methods for comparison: abuts, contains, encloses, equals, intersection, isBefore, isAfter, isConnected, overlaps, span, and 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.

    Start with your LocalDate, and let that class determine the first moment of the day. The day does not always start at 00:00:00 because of anomalies such as Daylight Saving Time (DST).

    Specify a proper time zone name in 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 not true time zones, not standardized, and not even unique(!).

    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.

    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-Open approach. This means the beginning is inclusive while 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.


    About java.time

    The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

    The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

    To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

    You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

    Where to obtain the java.time classes?

    • 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 6 and 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.time classes.
      • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

    The ThreeTen-Extra project 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.

    0 讨论(0)
  • 2021-02-04 01:03

    Yes, isAfter is exclusive, otherwise it should probably have been named isEqualOrAfter or something similar.

    Solution: Use "not before" instead of "after", and "not after" instead of "before".

    boolean isBetweenInclusive(LocalDate start, LocalDate end, LocalDate target) {
        return !target.isBefore(start) && !target.isAfter(end);
    }
    
    0 讨论(0)
提交回复
热议问题