计算两个日期的差异

时间:2014-08-14 11:31:36

标签: java date timezone

我编写了一个小程序,用于打印两个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或其他库。

4 个答案:

答案 0 :(得分:3)

要达到所需的行为,您需要设置正确的时区,即GMT-00,因为使用您使用的构造函数创建的Date对象将是自1月1日以来的毫秒, 1970年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

答案 1 :(得分:2)

您的问题是您将持续时间视为Date。作为Date,1000毫秒没有任何意义,因为Date自纪元以来就是MS。请勿尝试将其转换为Date,只需将其用作long

如果您使用的是Java 8,请考虑Duration。或者你可以使用JodaTime。如果您只需要long

,这些似乎可能有些过分

根据您的问题,要格式化它,取决于您是否使用Java 8.如果是,请使用其Duration。否则,请使用JodaTime&持续时间,期间和期间格式。这在帖子中描述:

joda-time-period-to-string

我承认这是一个比其他人建议的时区更复杂的解决方案。但是,我认为这是一个更正确的解决方案。如果时间增量超过一天,则尤其如此。在这种情况下,这种解决方案将完全错误。

如果时间差值是24小时1秒,则HH:mm:ss.SSSSS的格式会显示00:00:01.00000而不是' 24:00:01.0000`

答案 2 :(得分:0)

实际上你正在以错误的方式使用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"));

答案 3 :(得分:0)

您将获得此运行时:01:00:01.000000毫秒:1000,因为您当前的时区是UTC + 01:00。为Dateformatter设置时区GMT-00。