2010-10-07 82 views
6

我有一个日期列表和当前日期。从列表中找到最近的日期

如何找到最接近当前日期的日期?

+1

你能更具体吗?这听起来像你有一个日期列表,你想找到离现在最近的那个?一个简短的代码示例将是有帮助的 – 2010-10-07 18:26:45

+0

-1请给出更多详细信息 – 2010-10-07 19:15:24

回答

2

遍历所有日期如下:
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

请给我一些例子 – 2010-10-07 18:32:50

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

很好的答案... – 2010-10-07 18:36:52

+0

@aioobe:为什么我们不能只比较getTime(不是Math.abs(d1.getTime() - 现在))? – 2010-10-07 18:42:50

+2

@Stas:因为它会以其他顺序排列“自然”的日期。我们想按照'now'的顺序排列。尽管智能解决方案即使OP是一个混蛋,这也值得+1。 – BalusC 2010-10-07 18:44:16

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,就把日期在NavigableSetTreeSet和使用方法lowerhigher

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