2010-10-07 27 views
6

Tengo una lista de fechas y una fecha actual.Buscar la fecha más cercana de una lista

¿Cómo puedo encontrar la fecha más cercana a la fecha actual?

+1

¿Podría ser más específico? Parece que tienes una lista de fechas y quieres encontrar la que está más cerca de ahora? Un ejemplo de código abreviado sería útil –

+0

-1 por favor brinde más detalles –

Respuesta

2

Bucle a través de todas las fechas con lo siguiente:
1. Tener una variable que mantiene un registro de la fecha actual más cercano
2. Tener una variable que es la diferencia entre la fecha actual y más cercana la fecha actual

Cuando encuentre una fecha con una diferencia menor a la de lo que está siguiendo (2), actualice la diferencia y la fecha más cercana actual

Al final, la fecha más cercana actual es la fecha más cercana en la colección

aquí está el código en 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

Por favor déme un ejemplo –

20

que haría uso de Collection.min con un comparador personalizado que "órdenes" las fechas según la distancia desde el momento actual.

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

Gran respuesta ... –

+0

@aioobe: Por qué no pudimos comparar solo getTime (no Math.abs (d1.getTime() - ahora))? –

+2

@Stas: Porque ordenaría las fechas "naturalmente". Queremos ordenar por diferencia con 'ahora'. Solución inteligente sin embargo. Esto merece un +1 a pesar de que el OP es un idiota. – BalusC

2

Puede probar este código:

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

Si la lista está ordenada, entonces usted puede utilizar Collections.binarySearch() para encontrar el lugar en el que la fecha dada se clasifica en la lista - la más cercana es ya sea inmediatamente después o justo antes de ese índice.

Para listas muy grandes, esto es mucho más rápido que las otras soluciones, pero por supuesto requiere que la lista sea ordenada. Si va a hacer una consulta de este tipo varias veces, valdría la pena (en cuanto a rendimiento) ordenar primero la lista.

1

Si puede utilizar un Set en lugar de un List, poner las fechas en un NavigableSet como TreeSet y utilizar los métodos lower y higher.

NavigableSet<Date> dates = new TreeSet<Date>(); 
// add some dates to dates 
Date now = new Date(); 
Date highestDateUpUntilNow = dates.lower(now); 
Cuestiones relacionadas