我正在以Unix时间戳格式从Ruby on Rails Web服务获取当前时间(即1970年1月1日起的秒数),服务器上的时区为UTC。
在Java中,我试图将本地当前时间转换为UTC时间。但每次它都会提前6+strong>分钟。我想得到UTC当前时间和服务返回时间的差值。我的Java代码是-
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
Date utc_current = new Date(System.currentTimeMillis());
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
long serverTime = 1424936268000L;
long resTime = sdf.getCalendar().getTimeInMillis() - serverTime;
System.out.println("Time Diff : " + resTime);
其中serverTime是我从Web服务获得的时间。resTime的值显示负值,大约为6+分钟。
所以我的问题是,为什么UTC时区给System.currentTimeMillis提前时间?
与@JB Nizet的注释中的假设相反,表达式sdf.getCalendar().getTimeInMillis()
和System.currentTimeMillis()
是不等价的。证明:
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
System.out.println("date via System.currentTimeMillis()=" + f.format(utc_current));
System.out.println("date via sdf.getCalendar()=" + f.format(new Date(resTime)));
输出:
date via System.currentTimeMillis()=2015-02-26T12:19:09
date via sdf.getCalendar()=1889-12-31T04:41:21
如果你仔细研究SimpleDateFormat
和DateFormat
的源代码,你会发现初始化部分的代码如下:
private void initializeDefaultCentury() {
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add( Calendar.YEAR, -80 );
parseAmbiguousDatesAsAfter(calendar.getTime());
}
结论是在DateFormat
-对象上严格避免方法getCalendar()
。它仅用作内部格式化和解析处理的中间可变对象。很难说这样随着时间的推移你会得到什么。而是直接使用System.currentTimeMillis()
来比较您的本地时间和服务器时间。
另一个问题是你使用的模式。"dd MM yyyy hh:MM:ss"可能不正确,因为它使用了1-12范围内的半天时钟小时,但缺少上午/下午的信息。最好使用图案符号HH。查看Web服务的文档以获得正确的格式。
确保服务器和客户端机器上的时钟同步。这6分钟可能只是两者之间的一个偏移。