计算两个日期的差值



我编写了一个小程序,它将打印两个Date对象之间的差异:

public static void main(final String[] args) throws Exception {
    final DateFormat df = new SimpleDateFormat("HH:mm:ss.SSSSSS");
    final Date start = Calendar.getInstance().getTime();
    Thread.sleep(1000);
    final Date end = Calendar.getInstance().getTime();
    final long startMilliseconds = start.getTime();
    final long endMilliseconds = end.getTime();
    final long runtimeMilliseconds = endMilliseconds - startMilliseconds;
    final Date runtime = new Date(runtimeMilliseconds);
    System.out.print("Start  : " + df.format(start));
    System.out.println("t Milliseconds: " + startMilliseconds);
    System.out.print("End    : " + df.format(end));
    System.out.println("t Milliseconds: " + endMilliseconds);
    System.out.print("Runtime: " + df.format(runtime));
    System.out.println("t Milliseconds: " + runtimeMilliseconds);
    System.out.println();
    System.out.println("Milliseconds from new Date object: " + runtime.getTime());
}

输出如下:

Start  : 13:24:54.000871     Milliseconds: 1408015494871
End    : 13:24:55.000871     Milliseconds: 1408015495871
Runtime: 01:00:01.000000     Milliseconds: 1000
Milliseconds from new Date object: 1000

毫秒之间的差异是正确的,但是新创建的Date对象增加了一个额外的小时。runtime对象的预期输出将是:00:00:01.000000。我认为这是因为我的时区(GMT+1)。我如何计算两个Date对象之间的差异,并获得一个新的Date对象,不包括额外的小时,回来?我想使用Joda-Time或其他库。

要达到您想要的行为,您需要设置正确的时区,即GMT-00,因为您使用的构造函数创建的Date对象将是自1970年1月1日00:00:00 GMT以来的毫秒。要做到这一点,只需设置DateFormat df:

df.setTimeZone(TimeZone.getTimeZone("GMT-00"));

立即在其实例化之后(然后StartEnd日期将与新时区一起显示)或在打印新的Date runtime之前(然后StartEnd日期将在您的本地时区显示);之后,如果您想保留它以备将来使用,您可以重置原始的本地时区。

输出将是你想要的:

Start  : 11:51:37.000287     Milliseconds: 1408017097287
End    : 11:51:38.000287     Milliseconds: 1408017098287
Runtime: 00:00:01.000000     Milliseconds: 1000
Milliseconds from new Date object: 1000

您的问题是您将时间持续时间视为Date。1000ms作为Date没有任何意义,因为Date是自epoch以来的ms。不要试图将其转换为Date,只使用它作为long

如果您正在使用Java 8,请考虑Duration。或者你可以使用JodaTime。如果你只需要long,似乎这些可能是多余的。

根据你的问题,格式化它取决于你是否使用Java 8。如果是,使用它的Duration。否则,使用JodaTime &Duration, Period和PeriodFormatter。这是在文章中描述的:

joda-time-period-to-string

我承认这是一个比其他人建议的设置时区更复杂的解决方案。然而,我认为这是一个更正确的解决方案。如果时间差超过一天,这一点尤其正确。在这种情况下,这个解决方案是完全错误的。

如果时间增量是24小时1秒,你的HH:mm:ss.SSSSS格式将显示00:00:01.00000而不是'24:00:01.000 '

实际上您正在使用Date类,更具体地说,SimpleDateFormat类错误的方式。

你在你的问题中写的一切都是正确的:runtime对象中的额外小时是由于你的时区(GMT+1)。

你的runtime对象的内部表示是time = 1000,即它是00:00:01 of January 1, 1970 GMT

如果你想准确地看到这个日期,你应该以适当的方式修改你的格式化器:

    final DateFormat dfGmt0 = new SimpleDateFormat("HH:mm:ss.SSSSSS");
    dfGmt0.setTimeZone(TimeZone.getTimeZone("GMT+0"));

你得到这个Runtime: 01:00:01.000000毫秒:1000,因为你当前的时区是UTC+01:00。为Dateformatter设置时区GMT-00。

相关内容

  • 没有找到相关文章

最新更新