简体   繁体   中英

Date Util in java that will explode date range in weeks,month,quarter,year

I am looking for a java library that when given from and to date would return a list of dates in weeks,months,quarter or year which ever is most applicable. I have done this manually and i wanted to know if this is already implemented and tested as a part of a standard package.

Example

Given 1/1/2009 , 1/4/2009 it should give 1/1/2009,1/2/2009,1/3/2009,1/4/2009

Given 1/1/2009 , 1/14/2009 it should give 1/1/2009,1/7/2009,1/14/2009

hope you that is clear :)

The DateTime class provided by Joda Time has methods such as plusDays(int) , plusWeeks(int) , plusMonths(int) which should help.

Assuming you want to get all the dates between start and end in weeks (pseudocode):

DateTime start = // whatever
DateTime end = // whatever

List<DateTime> datesBetween = new ArrayList<DateTime>();

while (start <= end) {
   datesBetween.add(start);
   DateTime dateBetween = start.plusWeeks(1);
   start = dateBetween;
}

Alternative to Jado is use standart java API

Calendar start = // whatever
Calendar end = // whatever

List<Calendar> datesBetween = new ArrayList<Calendar>();

while (start.compareTo(end) <= 0) {
   datesBetween.add(start);
   Calendar dateBetween = start.add(Calendar.DAY_OF_MONTH, 7);
   start = dateBetween;
}

A sample java implementation using jodatime to create a date split over a large range, with minimal memory footprint.

https://github.com/atulsm/Test_Projects/blob/master/src/DateSplitter.java

java.time

The Answer by Dónal using Joda-Time is correct, but outdated. The Joda-Time team has advised that we should migrate to the java.time framework built into Java 8 and later. Much of the java.time functionality has been back-ported to Java 6 & 7 and further adapted to Android .

LocalDate

For a date-only value, without time-of-day and without time zone, use the LocalDate class.

Half-Open

Generally the best practice in handling a span of time is known as Half-Open. In this approach, the beginning of the span is inclusive while the ending is exclusive . So with the example code below, you will see the results do not include the stop date. If you insist on the ending being inclusive, change the date.isBefore ( stop ) to ! date.isAfter ( stop ) ! date.isAfter ( stop ) .

Example code

In its current state, the Question is vague, not addressing issues such as whether to consider if the start date happens to align with start of week or start of month and so on. Another issue: whether to use the Half-Open approach or not. So those issues are left as an exercise for the reader. ;-)

This code counts the number of days in the span of time. If under a week, we loop day-by-day. If over a week, we loop week-by-week. The same logic could be extended to handle month-by-month, quarter-by-quarter, and year-by-year as mentioned in the Question.

LocalDate start = LocalDate.of ( 2016 , Month.JANUARY , 2 );
LocalDate stop = start.plusDays ( 4 );
// LocalDate stop = start.plusWeeks ( 4 );

long days = ChronoUnit.DAYS.between ( start , stop );
List<LocalDate> dates = new ArrayList<> ();

if ( days == 0 ) {
    dates.add ( start );// Just one date, as start equals stop.

} else if ( days < 7 ) {  // Under a week, count day-by-day.
    LocalDate date = start;
    do {
        dates.add ( date );
        // Prep for next loop.
        date = date.plusDays ( 1 );
    } while ( date.isBefore ( stop ) ); // Using “isBefore” for Half-Open approach where ending is exclusive. For inclusive, use “! isAfter”.

} else if ( days > 7 ) {  // Over a week, count week-by-week.
    LocalDate date = start;
    do {
        dates.add ( date );
        // Prep for next loop.
        date = date.plusWeeks ( 1 );
    } while ( date.isBefore ( stop ) ); // Using “isBefore” for Half-Open approach where ending is exclusive. For inclusive, use “! isAfter”.

} else {
    // FIXME: ERROR. Should not be possible.
}

Dump to console.

System.out.println ( "start: " + start + " | stop: " + stop + " | dates: " + dates );

When run with the line for stop adding 4 days :

start: 2016-01-02 | stop: 2016-01-06 | dates: [2016-01-02, 2016-01-03, 2016-01-04, 2016-01-05]

When run with the line for stop adding 4 weeks :

start: 2016-01-02 | stop: 2016-01-30 | dates: [2016-01-02, 2016-01-09, 2016-01-16, 2016-01-23]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM