我编写了以下测试代码。
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss",Locale.JAPAN);
Date date1 = format.parse("08:00:01");
Date date2 = format.parse("23:00:05");
Date date = new Date(date2.getTime() - date1.getTime());
System.out.println(format.format(date));
但令我惊讶的是结果是 00:00:04
,我不明白为什么。
如果我将date2
更改为“08:00:01”,结果将更改为09:00:00
。
怎么会发生这种事?
最佳答案
Date
是一种表示时刻(时刻)的类型,而不是表示时间间隔(时间)的类型。
因此,如果您想计算两个时间点(Date 对象)之间的时间差(time inverval),您将得到另一种类型的时间差,例如 long
(以秒为单位)或输入外部库。
引用http://www.mkyong.com/java/how-to-calculate-date-time-difference-in-java/
第一个代码不使用外部库,但您必须将毫秒转换为秒、分钟、小时等。
这是重要的部分:
Date d1 = ...;
Date d2 = ...;
//in milliseconds
long diff = d2.getTime() - d1.getTime();
long diffSeconds = diff / 1000 % 60;
long diffMinutes = diff / (60 * 1000) % 60;
long diffHours = diff / (60 * 60 * 1000) % 24;
long diffDays = diff / (24 * 60 * 60 * 1000);
System.out.print(diffDays + " days, ");
System.out.print(diffHours + " hours, ");
System.out.print(diffMinutes + " minutes, ");
System.out.print(diffSeconds + " seconds.");
第二个代码确实使用外部库 Joda-Time,它是 Time 最著名的 Java 库之一。
这是重要的部分:
DateTime dt1 = new DateTime(d1);
DateTime dt2 = new DateTime(d2);
System.out.print(Days.daysBetween(dt1, dt2).getDays() + " days, ");
System.out.print(Hours.hoursBetween(dt1, dt2).getHours() % 24 + " hours, ");
System.out.print(Minutes.minutesBetween(dt1, dt2).getMinutes() % 60 + " minutes, ");
System.out.print(Seconds.secondsBetween(dt1, dt2).getSeconds() % 60 + " seconds.");
如果您想使用 Joda-Time 库,您还可以使用另一种类型的时间间隔,Interval
:http://joda-time.sourceforge.net/key_interval.html
Date
类使用内部 long 变量来表示时间点。
长值是某个时刻之间的时间差(以毫秒为单位),
即 January 1, 1970, 00:00:00 GMT
(在 http://docs.oracle.com/javase/7/docs/api/java/util/Date.html 中指定),
这是日本标准时间 1970 年 1 月 1 日 09:00:00
,因为 JST (UTC +09:00)。
因此,23:00:05 - 08:00:01 将变为 15:00:04,并将转换为日本标准时间 (UTC +09:00) = 24:00:04(1970 年 1 月 1 日) ),即 00:00:04(1970 年 1 月 2 日)。
如果计算 08:00:01 - 08:00:01,则 UTC 为 1970-01-01 00:00:00,日本为 1970-01-01 09:00:00标准时间。
<小时/> EDIT2:我犯了一些错误。我在解析时没有使用日本标准时间。无论如何,结果是一样的。date1 = 08:00:01 in Japan = 23:00:01 in UTC date2 = 23:00:05 in Japan = 14:00:05 in UTC date = 14:00:05 in UTC - 23:00:01 in UTC = 15:00:04 in UTC = 23:00:05 in Japan - 08:00:01 in Japan = 15:00:04 in UTC (NOT in JAPAN)为什么?因为计算是用我之前提到的长值完成的,该长值是在GMT(UTC +00:00,或只是UTC)中计算的。 即使您指定使用日本时间,长值也采用 UTC 格式。
Date
将其转换为 UTC 存储,因此它将获取您给出的 -09:00
时间,并且 Date
中的内部过程是通过世界标准时间。如果要打印,日期
只需添加+09:00
计算即可。
您还可以将其视为:
23:00:05 (+09:00) - 08:00:01 (+09:00) = 15:00:04 (+00:00)
无论如何,15:00:04 UTC
是 00:00:04 JST
,所以如果您打印它,您将看到日本时间 00: 00:04
因为您指定您使用的是日本标准时间。
关于Java计算时差误差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21059072/