用 joda time 计算平均时间
calculate an average time with joda time
我有很多时间戳显示用户进入房间的时间。我想计算平均时间。当某些动作发生在晚上时,就会出现问题。
我试着用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());
此代码,例如returns值14:08:54.333
。因为时间00:00 and 23:00
——以毫秒计算——彼此相差太远。
请帮我找到计算平均时间的正确方法?
一种天真的方法是收集所有日期中的 long
毫秒值,将它们相加并除以日期数,将它们转换回 LocalDate。不过,您可能需要一个 BigInteger 来保存总和。
三件事:
您必须定义一个偏移时间:
如果你想在不知道日期的情况下求出不同日期的平均时间,你必须自己定义一个偏移时间。这个时间用来判断一个时间是否属于第二天。
这个偏移时间可能会根据你得到的值推导出来。
如果没有偏移时间,您将隐含地使用 0 点钟。
避免溢出:
如果您的 times
列表变长,并且 long
字段不足以存储累积值,您可能 运行 溢出。您可以使用像 BigInteger
这样的防溢出数据结构或使用 (culmulative) moving average 方法。
错误的结果构造函数:
构造函数 LocalTime(long instant)
隐含地使用本地 DateTimeZone
从 Instant
计算本地时间。这会导致在不同时区之间使用相同代码时出现不同时间。
您要使用的方法是 LocalTime#fromMillisOfDay
.
考虑到以上几点,这里有一个方法:
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
我有很多时间戳显示用户进入房间的时间。我想计算平均时间。当某些动作发生在晚上时,就会出现问题。 我试着用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());
此代码,例如returns值14:08:54.333
。因为时间00:00 and 23:00
——以毫秒计算——彼此相差太远。
请帮我找到计算平均时间的正确方法?
一种天真的方法是收集所有日期中的 long
毫秒值,将它们相加并除以日期数,将它们转换回 LocalDate。不过,您可能需要一个 BigInteger 来保存总和。
三件事:
您必须定义一个偏移时间:
如果你想在不知道日期的情况下求出不同日期的平均时间,你必须自己定义一个偏移时间。这个时间用来判断一个时间是否属于第二天。
这个偏移时间可能会根据你得到的值推导出来。
如果没有偏移时间,您将隐含地使用 0 点钟。避免溢出:
如果您的times
列表变长,并且long
字段不足以存储累积值,您可能 运行 溢出。您可以使用像BigInteger
这样的防溢出数据结构或使用 (culmulative) moving average 方法。错误的结果构造函数:
构造函数LocalTime(long instant)
隐含地使用本地DateTimeZone
从Instant
计算本地时间。这会导致在不同时区之间使用相同代码时出现不同时间。
您要使用的方法是LocalTime#fromMillisOfDay
.
考虑到以上几点,这里有一个方法:
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