用joda时间计算平均时间

时间:2015-10-19 09:42:56

标签: java jodatime

我有很多时间戳显示用户何时进入房间。我想计算平均时间。当某些动作在夜间发生时会出现问题。 我试着用milis计算它,但这是错误的。

ArrayList<String> times = new ArrayList<String>();

    times.add("00:20:01");
    times.add("00:00:01");
    times.add("23:40:01");
    times.add("23:20:01");
    times.add("23:20:01");
    times.add("00:20:01");
    times.add("23:40:01");
    times.add("23:40:01");
    times.add("00:00:01");
    long commonMillis=0;
    for (String date:times){
        LocalTime time = new LocalTime(date);
        long dayMilis = time.getMillisOfDay();
        commonMillis = commonMillis + dayMilis;
    }
    LocalTime average = new LocalTime(commonMillis/times.size());

例如,此代码返回值14:08:54.333。因为以毫秒计算的小时数00:00 and 23:00彼此相距太远。

请帮我找到计算平均时间的正确方法?

2 个答案:

答案 0 :(得分:0)

一种天真的方法是在所有日期中收集long毫秒值,将它们相加并将它们除以日期数,然后将它们转换回LocalDate。但是,您可能需要一个BigInteger来保存总和。

答案 1 :(得分:0)

三件事:

  1. 您必须定义偏移时间:
    如果您想要在不知道当天的情况下平均不同天数,则必须自己定义偏移时间。此时间用于决定时间是否属于第二天 可以根据您获得的值导出此偏移时间 没有偏移时间,你隐含使用0点钟。

  2. 避免溢出:
    如果times列表变长,如果long字段不足以存储累计值,则可能会遇到溢出。您可以使用像BigInteger那样溢出的数据结构,或使用(culmulative) moving average方法。

  3. 错误的结果构造函数:
    构造函数LocalTime(long instant)隐含地使用您的本地DateTimeZone来计算Instant的本地时间。在不同时区之间使用相同代码时,这会导致不同的时间 您要使用的方法是LocalTime#fromMillisOfDay

  4. 考虑到以上几点,这是一种方法:

        long movingAverage = 0;
    
        // 1. define offset
        LocalTime offset = new LocalTime("12:00:00");
        long offsetMillis = offset.getMillisOfDay();
    
        for (String date : times) {
            long sampleMillis = new LocalTime(date).getMillisOfDay();
    
            // align to offset
            if (sampleMillis < offsetMillis)
                sampleMillis += DateTimeConstants.MILLIS_PER_DAY;
    
            long diff = sampleMillis - offsetMillis;
    
            // 2. use moving average
            movingAverage = movingAverage + diff / times.size();
        }
    
        // 3. avoid LocalTime(long) constructor
        LocalTime result = offset.plusMillis((int) movingAverage);
        System.out.println(result); // 23:48:54.329