Date
不幸的是,JDK API严重损坏。我建议使用Joda时间库。
Joda Time具有时间间隔的概念:
Interval interval = new Interval(oldTime, new Instant());
编辑:顺便说一句,乔达有两个概念:Interval
用于表示两个时刻之间的时间间隔(表示上午8点至上午10点之间的时间),以及Duration
表示没有实际时间界限的时间长度(例如表示两个小时!)
如果您只关心时间比较,则大多数Date实现(包括JDK)都会实现Comparable
接口,该接口可让您使用Comparable.compareTo()
/**
* Get a diff between two dates
* @param date1 the oldest date
* @param date2 the newest date
* @param timeUnit the unit in which you want the diff
* @return the diff value, in the provided unit
*/
public static long getDateDiff(Date date1, Date date2, TimeUnit timeUnit) {
long diffInMillies = date2.getTime() - date1.getTime();
return timeUnit.convert(diffInMillies,TimeUnit.MILLISECONDS);
}
然后您可以致电:
getDateDiff(date1,date2,TimeUnit.MINUTES);
以分钟为单位获取两个日期的差异。
TimeUnit
是java.util.concurrent.TimeUnit
,一个标准的Java枚举,范围从nanos到几天。
public static Map<TimeUnit,Long> computeDiff(Date date1, Date date2) {
long diffInMillies = date2.getTime() - date1.getTime();
//create the list
List<TimeUnit> units = new ArrayList<TimeUnit>(EnumSet.allOf(TimeUnit.class));
Collections.reverse(units);
//create the result map of TimeUnit and difference
Map<TimeUnit,Long> result = new LinkedHashMap<TimeUnit,Long>();
long milliesRest = diffInMillies;
for ( TimeUnit unit : units ) {
//calculate difference in millisecond
long diff = unit.convert(milliesRest,TimeUnit.MILLISECONDS);
long diffInMilliesForUnit = unit.toMillis(diff);
milliesRest = milliesRest - diffInMilliesForUnit;
//put the result in the map
result.put(unit,diff);
}
return result;
}
输出类似于Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0}
,带有排序的单位。
您只需要将该映射转换为用户友好的字符串即可。
警告 上面的代码段计算了两个瞬间之间的简单差异。可能会在夏令时切换过程中引起问题,如本帖子所述。这意味着,如果您没有时间计算日期之间的差异,则可能会缺少日期/小时。
我认为日期差异是主观的,尤其是在几天内。你可以:
计算24h经过的时间:day + 1-day = 1 day = 24h
计算经过的时间,注意夏令时:day + 1-day = 1 = 24h(但使用午夜时间和夏令时可能是0天和23h)
计算的数量day switches
,这意味着day + 1 1pm-day 11am = 1 day,即使经过的时间仅为2h(如果有夏令时,则为1h:p)
如果您对日期的日期差异的定义与第一种情况匹配,我的答案是有效的
如果您使用的是JodaTime,则可以使用以下两个日期(由Millies支持ReadableInstant)获取差异:
Interval interval = new Interval(oldInstant, new Instant());
// returns 4 because of the leap year of 366 days
new Period(LocalDate.Now(), LocalDate.Now().plusDays(365*5), PeriodType.years()).getYears()
// this time it returns 5
new Period(LocalDate.Now(), LocalDate.Now().plusDays(365*5+1), PeriodType.years()).getYears()
// And you can also use these static methods
Years.yearsBetween(LocalDate.Now(), LocalDate.Now().plusDays(365*5)).getYears()