2010-10-07 17 views
6

Tarihleri ​​ve güncel bir tarihim var.Listeden en yakın tarihi bul

Geçerli tarihe en yakın tarihi nasıl bulabilirim? Tüm tarihlerine kadar

+1

Daha spesifik olabilir misiniz? Bir Tarih Listesi'ne sahipsin gibi geliyor, ve şimdi en yakın olanı bulmak istiyor musun? Kısa kod örneği faydalı olurdu –

+0

-1 lütfen daha fazla ayrıntı verin –

cevap

2

Döngü aşağıdadır:
1. akım yakın tarihe izler bir değişken var
2. akım yakın tarihe ve geçerli tarih arasındaki farktır bir değişken var

(2) 'de takip ettiğiniz parçadan daha az fark içeren bir tarih bulduğunuzda, farkı ve güncel en güncel günkü güncelleştirmeyi düzeltin.

Sonunda, en yakın tarih, en yakın tarihtir. koleksiyonda

burada python kod: Ben "emir" tarih geçerli saatten uzaklığa göre o özel karşılaştırıcı ile Collection.min kullanmayı tercih ediyorum

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

Lütfen bana bir örnek verin –

20

.

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

Harika bir yanıt ... –

+0

@aioobe: Neden sadece getTime karşılaştıramadık (Math.abs değil (d1.getTime() - Şimdi))? –

+2

@Stas: Aksi takdirde "doğal olarak" tarih siparişi verecekti. Biz 'şimdi' ile farkla sipariş vermek istiyoruz. Akıllı çözüm olsa da. OP bir pislik olsa bile bu bir +1 hak ediyor. – BalusC

2

Bu kodu deneyebilirsiniz: liste sıralanır ise

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

, o zaman belirli bir tarih listesine sıralanır olacaktır yer bulmak için Collections.binarySearch() kullanabilirsiniz - En yakın biridir bu endeksden hemen önce veya sonra sağa.

Çok büyük listeler için bu, diğer çözümlerden çok daha hızlıdır, ancak elbette listenin sıralanmasını gerektirir. Eğer böyle bir sorguyu birden çok kez yapacaksanız, listeyi ilk sıraya koymak (performans açısından geçerli) olacaktır.

1

Eğer TreeSet gibi bir NavigableSet tarihleri ​​koymak yerine List bir Set kullanmak ve yöntemlerini lower ve higher kullanabilirsiniz.

NavigableSet<Date> dates = new TreeSet<Date>(); 
// add some dates to dates 
Date now = new Date(); 
Date highestDateUpUntilNow = dates.lower(now); 
İlgili konular