Java 用时间戳计算时间

Java calculating time with timestamps

我正在尝试计算 2 个时间戳之间的时间差,这是代码:

        Calendar calendar = Calendar.getInstance();
        java.util.Date now = calendar.getTime();
        Timestamp currentTimestamp = new Timestamp(now.getTime());
        System.out.println("Current\n"+currentTimestamp);

        DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
        Date date = dateFormat.parse("28/02/2015");
        Timestamp timestampBefore = new Timestamp(date.getTime());
        System.out.println("Before\n"+timestampBefore);

        Timestamp calculated = new Timestamp(currentTimestamp.getTime() - timestampBefore.getTime());
        System.out.println("Calculated\n"+calculated);

输出:

Current
2015-02-28 12:12:40.975
Before
2015-02-28 00:00:00.0
Calculated
1970-01-01 13:12:40.975
  1. 我能理解为什么它 returns 1970-01-01 但为什么它 return 13:12:40.975 ,1 小时多?

  2. 如何计算两个日期之间的差异所以输出是这样的(基于这个例子):
    Years:0、Months:0、Days:0、Hours:12、Minutes:12、Seconds:40?

更新:对于低于 1.8 的 java,请查看 http://www.joda.org/joda-time/index.html
对于 java 1.8,请参阅答案。

此处类似的解决方案: Java 8: Calculate difference between two LocalDateTime

(1) 时间戳是一个时间点。如果你计算两个时间戳之间的差异,结果不是时间戳(时间点),而是持续时间。所以将差异转换为时间戳是无稽之谈,因此讨论结果奇怪的原因是无用的。

(2) 您可能应该使用新的 Java 8 time API(如果您能够使用 Java 8):

LocalTime now = LocalTime.now();
LocalTime previous = LocalTime.of(0, 0, 0, 0);
Duration duration = Duration.between(previous, now);

System.out.println(now);
System.out.println(previous);
System.out.println(duration);

请注意,这只是计算一天中两次之间的持续时间(时-分-秒)。如果您想包含日期信息,请改用 LocalDateTime

LocalDateTime nextFirework = LocalDate.now()
                             .with(TemporalAdjusters.firstDayOfNextYear())
                             .atTime(LocalTime.MIDNIGHT);
LocalDateTime now = LocalDateTime.now();

// duration (in seconds and nanos)
Duration duration = Duration.between(now, nextFirework);
// duration in total hours
long hours = now.until(nextFirework, ChronoUnit.HOURS);
// equals to: duration.toHours();

如果你想在 years/months/days/hours/seconds 中有 'normalized' 持续时间,令人惊讶的是没有直接支持。您可以自行将持续时间转换为天、小时、分钟和秒:

long d = duration.toDays();
long h = duration.toHours() - 24 * d;
long m = duration.toMinutes() - 60 * duration.toHours();
long s = duration.getSeconds() - 60 * duration.toMinutes();
System.out.println(d + "d " + h + "h " + m + "m " + s + "s ");

但请注意,将天数转换为月份和年份会有困难,因为每个月没有唯一的天数,一年可以是闰年,有 366 天。为此,您可以使用 Period,与 Duration 相反,此 class 与时间轴相关联。不幸的是,Period 只支持日期,不支持时间:

// period in years/months/days (ignoring time information)
Period p = Period.between(now.toLocalDate(), nextFirework.toLocalDate());
System.out.println(p); // or use p.getYears(), p.getMonths(), p.getDays()

所以您可能可以结合这两种方法 - 首先,根据日期计算 Period,然后使用时间计算 Duration。请注意,持续时间可能为负数,因此在以下情况下您必须注意这一点:

Duration dur = Duration.between(start.toLocalTime(), end.toLocalTime());
LocalDate e = end.toLocalDate();
if (dur.isNegative()) {
    dur = dur.plusDays(1);
    e = e.minusDays(1);
}
Period per = Period.between(start.toLocalDate(), e);
System.out.println(per.toString() + ", " + dur.toString());