2

This could be a possible duplicate question but still asking.

I have a list of date (dates are in unsorted)

1/5/2012,1/10/2012, 1/1/2012, 1/7/2012 (MM/dd/yyyy)( only date no timestamp)

First I sorted all dates using collections ref

Collections.sort(listOfDates);

Now listOfDates Contains dates in order. 1/1/2012, 1/5/2012, 1/7/2012, 1/10/2012

How can i get all missing dates from the sorted list?

missing dates - 1/2/2012 1/3/2012 1/4/2012 1/6/2012 1/8/2012 1/9/2012

I have a sample program , but not sure how to get it working with the above requirement

Sample Algo taken from this question

if (listOfDates!=null && !listOfDates.isEmpty()) {
 Date firstDate = listOfDates.get(0) //contains the start date
 Date lastDate = listOfDates.get(listOfDates.size()-1); //contains end date 
}
Community
  • 1
  • 1
Namita
  • 779
  • 4
  • 12
  • 24

4 Answers4

3

Why not use the first and last dates in that sorted set to generate a list of dates between two dates? This answer uses jodaTime.

Community
  • 1
  • 1
Evan Mulawski
  • 54,662
  • 15
  • 117
  • 144
2

Use List-interfaces' removeAll -method with a list containing dates between your lowest (start date) and highest (end date) -values:

@Test
public void testAddMissingDates()
{
    List<Date> listOfDates = new ArrayList<Date>();
    //1/1/2012, 1/5/2012, 1/7/2012, 1/10/2012
    Calendar cal = Calendar.getInstance();
    cal.setTimeInMillis(0); //To zero out hour, minute, second ...
    cal.set(2012, 0, 1);    //Calendar.set: Month value is 0-based. e.g., 0 for January.
    listOfDates.add(cal.getTime());
    cal.set(2012, 0, 5);
    listOfDates.add(cal.getTime());
    cal.set(2012, 0, 7);
    listOfDates.add(cal.getTime());
    cal.set(2012, 0, 10);
    listOfDates.add(cal.getTime());

    Collections.sort(listOfDates);

    List<Date> resultingDates = generateDateListBetween(listOfDates.get(0), listOfDates.get(listOfDates.size()-1));

    //Remove all dates in listOfDates
    resultingDates.removeAll(listOfDates);

    for(Date date : resultingDates)
    {
        System.out.println(date);
    }       
}

private List<Date> generateDateListBetween(Date startDate, Date endDate)
{
    //Flip the input if necessary, to prevent infinite loop
    if(startDate.after(endDate))
    {
        Date temp = startDate;
        startDate = endDate;
        endDate = temp;
    }

    List<Date> resultList = new ArrayList<Date>();
    Calendar cal = Calendar.getInstance();
    cal.setTime(startDate);

    do
    {
        resultList.add(cal.getTime());
        cal.roll(Calendar.DAY_OF_MONTH, true);  //Roll one day forwards         
    }
    while(cal.getTime().before(endDate));

    return resultList;
}

Output:

Mon Jan 02 02:00:00 EET 2012
Tue Jan 03 02:00:00 EET 2012
Wed Jan 04 02:00:00 EET 2012
Fri Jan 06 02:00:00 EET 2012
Sun Jan 08 02:00:00 EET 2012
Mon Jan 09 02:00:00 EET 2012
esaj
  • 15,875
  • 5
  • 38
  • 52
1

Avoid legacy date-time types

Assuming you meant java.sql.Date objects, covert those to LocalDate objects. And sort.

List< LocalDate > dates = 
    inputs
    .stream()
    .map( java.sql.Date :: toLocalDate )
    .sorted()
    .toList() ;

Stream all dates in between first and last

Get the first and last dates. Make a stream of all dates in between. Filter those for dates not found amongst the originals.

    List < LocalDate > missing = 
        dates.get( 0 )
            .datesUntil( dates.get( dates.size() - 1 ) ) // Until last date
            .filter( date -> ! dates.contains( date ) ) 
            .toList() ;

Dump to console.

    System.out.println( dates ) ;
    System.out.println( missing ) ;

List#removeAll

Or, as commented by Mark Peters, use List#removeAll.

List < LocalDate > missing = 
        dates.get( 0 )
            .datesUntil( dates.get( dates.size() - 1 ) ) // Until last date
            .toList() ;
missing = new ArrayList<>( missing ) 
missing.removeAll( dates ) ;  // Caution: Resulting list is modifiable. 
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0

Write a method which takes two dates as argument and generates all the dates between these two dates. Now invoke this method for the sorted pair (example element i and i+1, and so on, the loop being from 0 to size of the list-1)of data in your sorted list.

Scorpion
  • 3,938
  • 24
  • 37
  • 2
    If you have a set or list of all the dates between the start and end date, then you can actually just do `Set missingDates = allDates; missingDates.removeAll(existingDates);` – Mark Peters Jan 20 '12 at 17:26