Java计算时差误差

Java计算时差误差,java,date,time,Java,Date,Time,我编写了以下测试代码 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.forma

我编写了以下测试代码

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
。 这是怎么发生的呢?

我会使用,但是,从这段代码(只需将代码包装到适当的java类中):

我得到:

07:00:04
这是在Mac OS X Mavericks上的JDK1.7.0(40上。

我会使用,但是,从这段代码(只是将代码包装到适当的java类中):

我得到:

07:00:04

这是在Mac OS X Mavericks上的JDK 1.7.0(U 40)上。日期是一个时间瞬间的类型(時刻), 没有时间间隔(時間).

因此,如果您想计算两个时间点(日期对象)之间的时差(time inverval),您将获得另一种类型的时差,例如
long
(以秒为单位)或在外部库中键入

第一个代码不使用外部库,但必须将毫秒转换为秒、分钟、小时等

以下是重要部分:

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.");
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,它是最著名的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.");
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时间库,还可以使用另一种类型的时间invervals,
Interval


编辑
Date
类使用内部长变量来表示时间瞬间

long值是某个时间瞬间之间的时间差,以毫秒为单位,
1970年1月1日00:00:00 GMT
(在中指定),
这是日本标准时间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) date1=08:00:01(日本)UTC=23:00:01 date2=23:00:05(日本)=14:00:05(UTC) 日期=UTC中的14:00:05-UTC中的23:00:01=UTC中的15:00:04 =23:00:05在日本-08:00:01在日本=15:00:04在UTC(不在日本) 为什么?因为计算是用我前面提到的长值完成的,它是在GMT中计算的(UTC+00:00,或仅UTC)。 即使您指定使用的是日本时间,
Date
也会将其转换为UTC,因此它会得到您给定的时间
-09:00
,并且
Date
中的内部过程是使用UTC完成的。如果要打印它,
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
,因为您指定您使用的是日本标准时间。

Date
是时间瞬间的类型(時刻), 没有时间间隔(時間).

Date date = new Date(date2.getTime() - date1.getTime());
因此,如果您想计算两个时间点(日期对象)之间的时差(time inverval),您将获得另一种类型的时差,例如
long
(以秒为单位)或在外部库中键入

第一个代码不使用外部库,但必须将毫秒转换为秒、分钟、小时等

以下是重要部分:

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.");
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,它是最著名的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.");
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时间库,还可以使用另一种类型的时间invervals,
Interval


编辑
Date
类使用内部长变量来表示时间瞬间

long值是某个时间瞬间之间的时间差,以毫秒为单位,
1970年1月1日00:00:00 GMT
(在中指定),
这是日本标准时间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) date1=08:00:01(日本)UTC=23:00:01 date2=23:00:05(日本)=14:00:05(UTC) 日期=UTC中的14:00:05-UTC中的23:00:01=UTC中的15:00:04 =23:00:05在日本-08:00:01在日本=15:00:04在UTC(不在日本) 为什么?因为计算是用我前面提到的长值完成的,它是在GMT中计算的(UTC+00:00,或仅UTC)。 即使您指定使用的是日本时间,
Date
也会将其转换为UTC,因此它会得到您给定的时间
-09:00
,并且
Date
中的内部过程是使用UTC完成的。如果要打印它,
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
,因为您指定要使用