2010-10-07 12 views
6

У меня есть список дат и текущей даты.Найти ближайшую дату из списка

Как найти ближайшую к текущему дату дату?

+1

Не могли бы вы уточнить? Похоже, у вас есть список дат, и вы хотите найти тот, который ближе всего к настоящему времени? Пример кода короткого кода будет полезен –

+0

-1, пожалуйста, дайте более подробную информацию –

ответ

2

Loop через все даты со следующим:
1. Иметь переменную, которая отслеживает текущей ближайшей дату
2. Есть переменный, которая представляет собой разницу между текущей ближайшей датой и текущей датой

Если вы находите дату с разницей меньше, чем та, что вы отслеживаете в (2), обновите разницу и текущую ближайшую дату

В конце ближайшая дата ближайшего дня в сборе

вот код в 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 
+0

, пожалуйста, дайте мне пример –

20

Я хотел бы использовать Collection.min с пользовательским компаратором, что «заказы» дата в соответствии с расстоянием от текущего времени.

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); 
    } 
}); 
+1

Отличный ответ ... –

+0

@aioobe: Почему мы не смогли сравнить только getTime (не Math.abs (d1.getTime() - Теперь))? –

+2

@Stas: Потому что в противном случае он заказывал даты «естественно». Мы хотим заказать по разнице с 'now'. Разумное решение. Это заслуживает +1, хотя OP является рывком. – BalusC

2

Вы можете попробовать этот код:

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()); 
} 
4

Если список отсортирован, то вы можете использовать Collections.binarySearch(), чтобы найти место, где данная дата будет отсортирован в списке - ближайший один является либо сразу, либо прямо перед этим индексом.

Для очень больших списков это намного быстрее, чем другие решения, но, конечно, для этого требуется сортировка списка. Если вы собираетесь делать такой запрос несколько раз, было бы целесообразно сначала отсортировать список.

1

Если вы можете использовать Set вместо List, поставить даты в NavigableSet таких как TreeSet и использовать методы lower и higher.

NavigableSet<Date> dates = new TreeSet<Date>(); 
// add some dates to dates 
Date now = new Date(); 
Date highestDateUpUntilNow = dates.lower(now); 
Смежные вопросы