在Java中,如何获得两个日期之间的秒数差异?


77

Java类库具有一个名为DateTime的类。DateTime具有此方法:

int daysBetween(DateTime other)

该参数返回此参数与参数之间的天数。它没有方法

int secondsBetween(DateTime other)

我碰巧需要的。是否有一个类似于DateTime但有这种方法的类?



1
如果您使用的是Java 8,还有更多选择,请参见stackoverflow.com/q/25747499/32453
rogerdpack

Answers:


182

不熟悉DateTime ...

如果您有两个日期,则可以对它们调用getTime以获取毫秒,获取diff并除以1000。例如

Date d1 = ...;
Date d2 = ...;
long seconds = (d2.getTime()-d1.getTime())/1000;

如果您有日历对象,则可以调用

c.getTimeInMillis()

并做同样的事情


2
当时间差不是很高时-int seconds =(int)((d2.getTime()-d1.getTime())/ 1000);
Xdg 2013年

@sebrock-固定为长型显示-将int强制转换为较小的数量
Scott Stanchfield 2013年

1
@Xdg我最近在设计一个界面,遇到了同样的“问题”,但是Integer.MAX_VALUE可以代表将近70年的时间。这对我来说足够了。
mike

我正在寻找使用LocalDateTime的答案。
JohnMerlino 2014年

12

我想提供现代的答案。当问这个问题时,其他答案都很好,但是时间还在继续。今天,我建议您使用java.time现代的Java日期和时间API

    ZonedDateTime aDateTime = ZonedDateTime.of(2017, 12, 8, 19, 25, 48, 991000000, ZoneId.of("Europe/Sarajevo"));
    ZonedDateTime otherDateTime = ZonedDateTime.of(2017, 12, 8, 20, 10, 38, 238000000, ZoneId.of("Europe/Sarajevo"));

    long diff = ChronoUnit.SECONDS.between(aDateTime, otherDateTime);
    System.out.println("Difference: " + diff + " seconds");

打印:

Difference: 2689 seconds

ChronoUnit.SECONDS.between()适用于两个ZonedDateTime对象或两个OffsetDateTime,两个LocalDateTime,等等。

如果您只需要几秒钟,那么您应该考虑使用Duration该类:

    Duration dur = Duration.between(aDateTime, otherDateTime);
    System.out.println("Duration: " + dur);
    System.out.println("Difference: " + dur.getSeconds() + " seconds");

打印:

Duration: PT44M49.247S
Difference: 2689 seconds

两行中的前一行以ISO 8601格式打印持续时间,输出表示持续时间为44分钟49.247秒。

为什么选择java.time?

Date在其他几个答案中使用的类现在已经过时了。Joda-Time在几个(可能还有一个问题)中也使用过,现在处于维护模式,没有计划进行重大增强,并且开发人员正式建议迁移到java.time,也称为JSR-310。

问:我可以在Java版本中使用现代API吗?

如果至少使用Java 6,则可以。


答案很低估。Jodatime的计算有点混乱。但是ChronoUnit.SECONDS.between(oldDate.toInstant(), newDate.toInstant())相当容易记住。
anon58192932'4

10

你应该做

org.joda.time.Seconds.secondBetween(date1, date2)

3
欢迎使用StackOverflow,并感谢您的贡献。如果您解释了为什么要走这条路,那么这篇文章会更好。
Phil

5
@divonas没有区别。他的表达方式明确提到了乔达
蒂姆

1
正确的方法名称是“ second s Between”。就是说,这是我在org.joda.time.DateTime中找到的最干净的方法。
thisismydesign's

1
如果希望将结果作为整数,则应在结果上调用getSeconds()。Seconds.secondsBetween(start, end).getSeconds()
thisismydesign's

1
我认为现在有一种Java 8的方法不需要jodatime。我正在寻找它。
anon58192932 '11

7

应该这样做:

Date a = ...;
Date b = ...;

Math.abs(a.getTime()-b.getTime())/1000;

这里是相关文档:Date.getTime()。请注意,这仅适用于格林尼治标准时间1970年1月1日00:00:00之后的日期


嗯,为什么这仅适用于1970年1月1日之后的日期?在此之前,值是负数,但算术运算是对负数进行的。
杰伊,

5

没有DateTime标准Java SE API中的此类。尽管在joda-time中有一个,但它甚至没有daysBetween方法。

使用标准Java API,在两个java.util.Date对象之间获取秒数的最简单方法是减去其时间戳并除以1000:

int secondsBetween = (date1.getTime() - date2.getTime()) / 1000;

3

不建议使用java.util.DateSystem.currentTimeMillis()测量经过的时间。这些日期不能保证是单调的,并且在修改系统时钟时(例如,从服务器更正后)会发生更改。很有可能这种情况很少发生,但是为什么不编写一个更好的解决方案,而不是担心可能的消极变化或非常大的变化?

相反,我建议使用System.nanoTime()

long t1 = System.nanoTime();
long t2 = System.nanoTime();

long elapsedTimeInSeconds = (t2 - t1) / 1000000000;

编辑

有关单调性的更多信息,请参见我询问的一个相关问题的答案,在可能的情况下,nanoTime使用单调时钟。我已经测试过,但仅使用Windows XP,Java 1.6并修改了时钟,nanoTimecurrentTimeMillis这不是单调的。

同样来自Java的实时文档

问:50。通过实时时钟返回的时间是否比System.nanoTime()返回的时间分辨率更高?

实时时钟和System.nanoTime()都基于相同的系统调用,因此也基于相同的时钟。

使用Java RTS,所有基于时间的API(例如,计时器,定期线程,截止日期监视等)都基于高分辨率计时器。并且,与实时优先级一起,它们可以确保针对实时约束在适当的时间执行适当的代码。相反,普通的Java SE API仅提供几种能够处理高分辨率时间的方法,而不能保证在给定时间执行。在代码的各个点之间使用System.nanoTime()进行经过时间的测量应始终准确。


嗯,有趣的帖子。是什么让您说nanoTime不受时钟更新的影响?我在Java文档中什么都没有看到。我并不是说您错了,我想知道您是否有参考文献或进行了实验以支持这一点。
杰伊,


2

您可以使用org.apache.commons.lang.time.DateUtils它来使其更清洁:

(firstDate.getTime() - secondDate.getTime()) / DateUtils.MILLIS_PER_SECOND

0

哪一堂课 ?您是说Joda DateTime类吗?如果是这样,您可以简单地调用getMillis()每个,然后执行适当的减法/缩放。

我推荐Joda从事日期/时间工作,顺便说一句,因为它有用且直观的API,并且它的格式化/解析选项具有线程安全性。


那不是一个标准库(Joda也不是),也不是特别知名的库(不同于Joda)
Brian Agnew

0

只是一个指针:如果要计算两个java.util.Date之间的差,则减去两个日期并将其除以1000的方法是合理的,但是要特别小心,如果从Calendar对象获取java.util.Date引用。如果这样做,则需要考虑TimeZone的夏令时,因为您使用的日期之一可能发生在DST期间。

在Prasoon的链接中对此进行了解释,我建议花一些时间阅读它。


0

使用此方法:

private Long secondsBetween(Date first, Date second){
    return (second.getTime() - first.getTime())/1000;
}

2
请为您的答案添加一些解释。
Alex Char 2015年

很明显,您需要发送两个Date,我的意思是Date initialDate = new Date()和Date finalDate = new Date(),因此,如果您发送initialDate和finalDate,则可以得到秒数的差……两者都将是使用getTIme方法将其“转换”为Long,最后,您将得到除以1000的差值以得到秒数...顺便说一句好答案!
Raul Guerrero
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.