计算两个 Java 日期实例之间的差异

新手上路,请多包涵

我在 Scala 中使用 Java 的 java.util.Date 类,想要比较 Date 对象和当前时间。我知道我可以使用 getTime() 计算增量:

 (new java.util.Date()).getTime() - oldDate.getTime()

然而,这只给我留下了代表毫秒的 long 。有没有更简单、更好的方法来获得时间增量?

原文由 pr1001 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 537
2 个回答

不幸的是,JDK Date API 被严重破坏了。我推荐使用 Joda Time 库

Joda Time 有一个时间 间隔 的概念:

 Interval interval = new Interval(oldTime, new Instant());

编辑:顺便说一下,Joda 有两个概念: Interval 表示两个时间点之间的时间间隔(表示上午 8 点到上午 10 点之间的时间),以及 Duration 表示长度没有实际时间界限的时间(例如代表两个小时!)

如果您只关心时间比较,大多数 Date 实现(包括 JDK 实现)实现 Comparable 允许您使用 Comparable.compareTo()

原文由 notnoop 发布,翻译遵循 CC BY-SA 4.0 许可协议

简单的差异(没有库)

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

以分钟为单位获取 2 个日期的差异。

TimeUnitjava.util.concurrent.TimeUnit ,一个从纳米到天的标准 Java 枚举。


人类可读的差异(没有库)

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

http://ideone.com/5dXeu6

输出类似于 Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0} ,带有有序的单位。

您只需将该映射转换为用户友好的字符串。


警告

上面的代码片段计算了 2 个瞬间之间的简单差异。它可能会在夏令时切换期间引起问题,如 本文 所述。这意味着如果您在没有时间的情况下计算日期之间的差异,您可能会缺少日期/小时。

在我看来,日期差异有点主观,尤其是在几天内。您可以:

  • 计算 24 小时经过的时间:天 + 1 - 天 = 1 天 = 24 小时

  • 计算经过时间的数量,注意夏令时:day+1 - day = 1 = 24h(但使用午夜时间和夏令时可能是 0 天和 23h)

  • 计算 day switches 的数量,这意味着 day+1 1pm - day 11am = 1 day,即使经过的时间仅为 2h(如果有夏令时则为 1h :p)

如果您对日期差异的定义符合第一种情况,我的回答是有效的

与 JodaTime

如果您使用的是 JodaTime,您可以获得 2 个瞬间(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()

原文由 Sebastien Lorber 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题