Find the closest date among several dates to a given date

I have a list of dates and current date. How can I find the date closest to the current date?

+7
java
source share
5 answers

I would use Collection.min using a special comparator that β€œorders” dates according to the distance from the current time.

 final long now = System.currentTimeMillis(); // Create a sample list of dates List<Date> dates = new ArrayList<Date>(); Random r = new Random(); for (int i = 0; i < 10; i++) dates.add(new Date(now + r.nextInt(10000)-5000)); // Get date closest to "now" Date closest = Collections.min(dates, new Comparator<Date>() { public int compare(Date d1, Date d2) { long diff1 = Math.abs(d1.getTime() - now); long diff2 = Math.abs(d2.getTime() - now); return Long.compare(diff1, diff2); } }); 
+22
source share

If the list is sorted, you can use Collections.binarySearch() to find the place where the given date will be sorted in the list - the closest of them is either on the right or on the right before this index.

For very large lists, this is much faster than other solutions, but, of course, this requires sorting the list. If you intend to make such a request several times, it would be advisable to sort the list first.

+4
source share

Scroll through all dates with the following:
1. Have a variable that tracks the current closest date
2. Have a variable that is the difference between the current closest date and the current date.

When you find a date with a difference less than the one you are tracking in (2), update the difference and the current nearest date

At the end, the current closest date is the closest date in the collection.

here is the code in python:

 dates = [date(2010,1,2), date(2010,5,6), date(2010,3,4), date(2011, 1, 2), date(2010,10,20), date(2009,2,3)] current_date = dates[0] current_min = abs(current_date - date.today()) for d in dates: if abs(d - date.today()) < current_min: current_min = abs(d - date.today()) current_date = d 
+2
source share

You can try this code:

 public static Date closerDate(Date originalDate, Collection<Date> unsortedDates) { List<Date> dateList = new LinkedList<Date>(unsortedDates); Collections.sort(dateList); Iterator<Date> iterator = dateList.iterator(); Date previousDate = null; while (iterator.hasNext()) { Date nextDate = iterator.next(); if (nextDate.before(originalDate)) { previousDate = nextDate; continue; } else if (nextDate.after(originalDate)) { if (previousDate == null || isCloserToNextDate(originalDate, previousDate, nextDate)) { return nextDate; } } else { return nextDate; } } return previousDate; } private static boolean isCloserToNextDate(Date originalDate, Date previousDate, Date nextDate) { if(previousDate.after(nextDate)) throw new IllegalArgumentException("previousDate > nextDate"); return ((nextDate.getTime() - previousDate.getTime()) / 2 + previousDate.getTime() <= originalDate.getTime()); } 
+2
source share

If you can use Set instead of List , put the dates in a NavigableSet like TreeSet , and use the lower and higher methods.

 NavigableSet<Date> dates = new TreeSet<Date>(); // add some dates to dates Date now = new Date(); Date highestDateUpUntilNow = dates.lower(now); 
+2
source share

All Articles