简体   繁体   English

获取两个java.util.Date的平均值

[英]Get Average of two java.util.Date

I have an array of java.util.Date objects. 我有一个java.util.Date对象的数组。 I am trying to find the average. 我想找到平均值。

For example, if I have 2 date objects with 7:40AM and 7:50AM. 例如,如果我在上午7:40和上午7:50有2个日期对象。 I should get an average date object of 7:45AM. 我应该得到一个平均日期对象上午7:45。

The approach I am thinking of is inefficient: 我想的方法效率低下:

  1. for loop through all dates for循环所有日期
  2. find difference between 0000 and time 找出0000和时间之间的差异
  3. add that time diff to a total 将时间差异添加到总数中
  4. divide that by the total count 除以总数
  5. convert that time to a date object 将该时间转换为日期对象

Is there an easier function to do this? 这样做有更简单的功能吗?

Well fundamentally you can just add up the "millis since the Unix epoch" of all the Date objects and find the average of those. 从根本上说,你可以将所有Date对象的“自Unix时代以来的毫秒”加起来并找到它们的平均值。 Now the tricky bit is avoiding overflow. 现在棘手的一点是避免溢出。 Options are: 选项包括:

  1. Divide by some known quantity (eg 1000) to avoid overflow; 除以一些已知量(例如1000)以避免溢出; this reduces the accuracy by a known amount (in this case to the second) but will fail if you have more than 1000 items 这会将准确度降低一个已知量(在本例中为第二个),但如果您有超过1000个项目则会失败
  2. Divide each millis value by the number of dates you're averaging over; 将每个millis值除以您平均的日期数; this will always work, but has hard-to-understand accuracy reduction 这将始终有效,但难以理解准确性降低
  3. Use BigInteger instead 请改用BigInteger

An example of approach 1: 方法1的一个例子:

long totalSeconds = 0L;
for (Date date : dates) {
     totalSeconds += date.getTime() / 1000L;
}
long averageSeconds = totalSeconds / dates.size();
Date averageDate = new Date(averageSeconds * 1000L);

An example of approach 3: 方法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());

With a lot of dates, taking the sum of all dates together will certainly go into an overflow. 有很多日期,把所有日期的总和放在一起肯定会溢出。 If you want to prevent that you should do it like this (in pseudo code): 如果你想防止你应该这样做(伪代码):

var first = dates.getFirst
var sumOfDifferences = 0
loop over all dates
    for each date sumOfDifferences += date - first
var averageDate = first + sumOfDifferences/countOfDates

This will never make you run in an overflow. 这绝不会让你在溢出中运行。

There's already an answer here: Sum two dates in Java 这里已经有了答案: 在Java中总结两个日期

You just need to sum up all your date objects using getTime() and then divide it by the number of objects and convert it back to a Date object. 您只需要使用getTime()汇总所有日期对象,然后将其除以对象数并将其转换回Date对象。 Done. 完成。

To avoid overflow in caluclation of average time: 为了避免平均时间的计算溢出:

first sort by date; 首先按日期排序;
store value of first date in time0 ; 存储第一个日期的时间值time0 ;

Caluclate the average of the deltaTimes by subtractiong first time0 from all times. 从所有时间开始通过减法第一次减去deltaTimes的平均值。 Then sum up and divide. 然后总结并划分。

The result = new Date(time0 + avgDeltas) ; 结果= new Date(time0 + avgDeltas) ;

Try this. 尝试这个。 In here each date convert to long value my getTime() . 在这里,每个日期转换为long值我的getTime() This will return mil-second value. 这将返回mil-second值。 Then we can proceed. 那我们就可以继续了。

   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));

一旦发布了java 8,就可以使用了

Date avgDate = new Date( LongStream.of(datesAsLongArray).sum() / datesAsLongArray.length * 1000);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM