Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find nearest date among several dates to a given date

Tags:

java

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

like image 572
salman raza Avatar asked Oct 07 '10 18:10

salman raza


4 Answers

Loop through all dates with the following:
1. Have a variable that keeps track of 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 that of the what you're keeping track of in (2), update the difference and the current closest date

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

here's 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
like image 111
MStodd Avatar answered Sep 28 '22 03:09

MStodd


I'd use Collection.min with a custom comparator that "orders" the dates according to distance from 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);
    }
});
like image 26
aioobe Avatar answered Oct 12 '22 01:10

aioobe


If the list is sorted, then you can use Collections.binarySearch() to find the place where the given date would be sorted into the list - the closest one is either right after or right before that index.

For very large lists, this is much faster than the other solutions, but of course it does require the list to be sorted. If you're going to do such a query multiple times, it would be worth it (performance-wise) to sort the list first.

like image 6
Michael Borgwardt Avatar answered Oct 12 '22 00:10

Michael Borgwardt


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

NavigableSet<Date> dates = new TreeSet<Date>();
// add some dates to dates
Date now = new Date();
Date highestDateUpUntilNow = dates.lower(now);
like image 5
Steve Kuo Avatar answered Oct 12 '22 01:10

Steve Kuo