我有非常简单的代码来计算两次之间的差异:
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
public class JavaApplication8 {
private static final SimpleDateFormat timeFormat = new SimpleDateFormat("hh:mm:ss.SSS");
public static void main(String[] args) throws InterruptedException {
Date start = GregorianCalendar.getInstance().getTime();
Thread.sleep(100);
Date end = GregorianCalendar.getInstance().getTime();
long diff = end.getTime() - start.getTime();
System.out.println(timeFormat.format(diff));
}
}
但它会打印01:00:00.100
而不是00:00:00.100
,为什么?
答案 0 :(得分:5)
解决此问题的其他方法。实际上你所拥有的时间差异不是当前时间的毫秒数。它只是时间差异,所以做一个简单的划分你可以有几个小时:分钟:秒。 它非常快。
Date start = GregorianCalendar.getInstance().getTime();
Thread.sleep(100);
Date end = GregorianCalendar.getInstance().getTime();
long longVal = end.getTime() - start.getTime();
long hours = longVal / 3600000;
long mins = (longVal % 3600) / 60000;
long secs = longVal % 60000;
System.out.println(hours + " " + mins + " " + secs);
答案 1 :(得分:4)
这是一个时区问题。默认情况下,DateFormat.format()
会将默认时区格式设置为UTC+1
。
您应该将timeFormat
的时区设为UTC
:
timeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(timeFormat.format(diff));
此外,您应该在DateFormat中使用HH
代替hh
。 hh
是12小时制。
new SimpleDateFormat("HH:mm:ss.SSS");
更新:
但还有其他一些重大问题。目前您正在尝试格式化持续时间,您不应该这样做。 Java Date API,没有任何句点或持续时间的概念。
您从格式化中获得的值只不过是来自纪元的毫秒数(相当于差异)。它正在返回一个Date
对象。虽然结果似乎是正确的,但从技术上讲,两个日期之间的差异表示一个时期或持续时间,这与日期(表示特定时刻)不同。
您应该考虑转移到此Joda Time此任务,该任务包含代表Period
,Instant
和Duration
等概念的类。
答案 2 :(得分:4)
你混淆了两个概念:
两者不兼容,你总会得到如此奇怪的效果。在你的情况下,正如其他评论中指出的那样,时区会混入。时区的概念仅存在于日期(时间点),但对于间隔没有意义。
您可以使用Jodatime库或JSR 310:日期和时间API(我认为Java 8附带)。
使用Jodatime,你可以明确地构建一个区间:
DateTime start = new DateTime(2004, 12, 25, 0, 0, 0, 0);
DateTime end = new DateTime(2005, 1, 1, 0, 0, 0, 0);
Period period = new Period(start, end);
然后使用PeriodFormatter
对其进行格式化PeriodFormatter daysHoursMinutes = new PeriodFormatterBuilder()
.appendDays()
.appendSuffix(" day", " days")
.appendSeparator(" and ")
.appendMinutes()
.appendSuffix(" minute", " minutes")
.appendSeparator(" and ")
.appendSeconds()
.appendSuffix(" second", " seconds")
.toFormatter();
System.out.println(daysHoursMinutes.print(period));
通过分离ONE时间点和两个时间点之间的时间概念,您可以确保没有任何其他意外(例如闰秒)。
答案 3 :(得分:0)
因为您的时区是GMT + 1。
If you read the documentation,您会找到getTime()
所做的事情:
返回自1970年1月1日00:00:00 GMT以来的毫秒数 由此Date对象表示。
所以100毫秒意味着January 1, 1970, 00:00:00.100 GMT
,即January 1, 1970, 01:00:00.100 GMT+1
。
您只需设置您希望时间转换为的时区:
timeFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
你想要24小时格式:HH:mm:ss.SSS
,否则它将显示12而不是00小时。
编辑:正如 jarnbjo 所说:你正在尝试将日期格式化程序应用到一段时间,这显然不会像你期望的那样工作。 Java API中没有这样的时间间隔格式化程序。你必须自己写。