Java用时间戳计算时间

时间:2015-02-28 11:19:56

标签: java date calendar timestamp

我试图计算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. 我可以理解为什么它会返回1970-01-01,但为什么它会再返回13:12:40.975 1小时?

  2. 如何计算2个日期之间的差异,所以输出是这样的(基于这个例子):
    年:0,月:0,天:0,小时:12,分钟:12,秒:40?

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

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

1 个答案:

答案 0 :(得分:4)

(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();

如果您想进行标准化'以年/月/日/小时/秒为单位的持续时间,令人惊讶的是没有直接的支持。您可以自行将持续时间转换为天,小时,分钟和秒:

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相反,此类与时间轴相关联。不幸的是,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());