2010-10-07 21 views
6

Ho un elenco di date e una data corrente.Trova la data più vicina da un elenco

Come trovare la data più vicina alla data corrente?

+1

Potrebbe essere più specifico? Sembra che tu abbia una lista di date e vuoi trovare quella più vicina ad ora? Un esempio di codice breve sarebbe utile –

+0

-1 per favore fornisci maggiori dettagli –

risposta

2

loop attraverso tutte le date con il seguente:
1. Avere una variabile che tiene traccia della data più vicina corrente
2. Avere una variabile che è la differenza tra la data più vicina corrente e la data corrente

Quando si trova un appuntamento con una differenza inferiore a quella della cosa si sta tenendo traccia di a (2), aggiornare la differenza e la data più vicina corrente

alla fine, la data più vicina corrente è la data più vicina nella collezione

ecco il codice 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 
+0

per favore dammi un esempio –

20

userei Collection.min con un comparatore personalizzato che "Ordini" le date in base alla distanza di tanto in corso.

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

Ottima risposta ... –

+0

@aioobe: Perché non siamo riusciti a confrontare solo getTime (non Math.abs (d1.getTime() - adesso))? –

+2

@Stas: Perché altrimenti ordinerebbe le date "naturalmente". Vogliamo ordinare per differenza con 'now'. Soluzione intelligente però. Questo merita un +1 anche se l'OP è un cretino. – BalusC

2

Si può provare questo codice:

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

Se la lista è ordinata, quindi è possibile utilizzare Collections.binarySearch() per trovare il luogo dove la data indicata sarebbe risolto nella lista - il più vicino è subito dopo o subito prima dell'indice.

Per elenchi molto grandi, questo è molto più veloce rispetto alle altre soluzioni, ma ovviamente richiede la lista da ordinare. Se hai intenzione di fare una tale domanda più volte, varrebbe la pena (in termini di prestazioni) di ordinare prima la lista.

1

Se è possibile utilizzare un Set invece di un List, mettere le date in un NavigableSet quali TreeSet e utilizzare i metodi lower e higher.

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