我编写了一个小程序,它将打印两个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"));
立即在其实例化之后(然后Start
和End
日期将与新时区一起显示)或在打印新的Date runtime
之前(然后Start
和End
日期将在您的本地时区显示);之后,如果您想保留它以备将来使用,您可以重置原始的本地时区。
输出将是你想要的:
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。