我有一组 java.util.Date 对象。我试图找到平均值。
例如,如果我有 2 个日期对象,分别是上午 7:40 和上午 7:50。我应该得到早上 7:45 的平均日期对象。
我正在考虑的方法效率低下:
- for 循环遍历所有日期
- 找出 0000 和时间之间的差异
- 将该时间差异添加到总数中
- 除以总数
- 将该时间转换为日期对象
有没有更简单的功能来做到这一点?
好吧,从根本上讲,您可以将所有对象的“自 Unix 纪元以来的毫秒数”相加Date
并找到它们的平均值。现在棘手的一点是避免溢出。选项是:
BigInteger
改为使用方法 1 的示例:
long totalSeconds = 0L;
for (Date date : dates) {
totalSeconds += date.getTime() / 1000L;
}
long averageSeconds = totalSeconds / dates.size();
Date averageDate = new Date(averageSeconds * 1000L);
方法 3 的示例:
BigInteger total = BigInteger.ZERO;
for (Date date : dates) {
total = total.add(BigInteger.valueOf(date.getTime()));
}
BigInteger averageMillis = total.divide(BigInteger.valueOf(dates.size()));
Date averageDate = new Date(averageMillis.longValue());
有很多日期,将所有日期加在一起肯定会溢出。如果你想防止你应该这样做(在伪代码中):
var first = dates.getFirst
var sumOfDifferences = 0
loop over all dates
for each date sumOfDifferences += date - first
var averageDate = first + sumOfDifferences/countOfDates
这永远不会让你在溢出中运行。
尝试这个。在这里,每个日期都转换为长值 my getTime()
。这将返回 mil-second 值。然后我们可以继续。
SimpleDateFormat sdf = new SimpleDateFormat("HH:mma");
Date date1=sdf.parse("7:40AM");
Date date2=sdf.parse("7:50AM");
long date1InMilSec=date1.getTime();
long date2InMilSec=date2.getTime();
System.out.println("Average "+sdf.format((date1InMilSec+date2InMilSec)/2));
这里已经有答案了:Sum two dates in Java
您只需要总结所有日期对象getTime()
,然后将其除以对象数量并将其转换回Date
对象。完毕。
为避免计算平均时间溢出:
首先按日期排序;
将第一个日期的值存储在time0
;
通过从所有时间减去 g first time0 来计算 deltaTimes 的平均值。然后总结和划分。
结果 = new Date(time0 + avgDeltas)
;
发布 java 8 后,您可以使用
Date avgDate = new Date( LongStream.of(datesAsLongArray).sum() / datesAsLongArray.length * 1000);