为什么UTC时区为Java中的System.currentTimeMillis提前了?

时间:2015-02-26 07:52:41

标签: java datetime time timezone

我从Unix时间戳格式的 RubyOnRails webservice获取当前时间(即1970年1月1日起的秒数),服务器上的时区为 UTC

在Java中我试图将本地当前时间转换为 UTC时间。但每次提前 6+分钟。我希望得到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 是我从webservice获取的时间。 resTime 的值显示负值,大约6分钟以上。

所以我的问题是为什么UTC时区为System.currentTimeMillis提前了?

请帮我解决此问题。

2 个答案:

答案 0 :(得分:3)

与@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

如果您仔细研究SimpleDateFormatDateFormat的源代码,您会在初始化部分代码中找到如下代码:

private void initializeDefaultCentury() {
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.add( Calendar.YEAR, -80 );
    parseAmbiguousDatesAsAfter(calendar.getTime());
}

结论是严格避免getCalendar() - 对象上的方法DateFormat 。它仅用作内部格式和解析处理的中间可变对象。通过这种方式很难说你会真正得到什么。而是直接使用System.currentTimeMillis()来比较您的本地时间和服务器时间。

另一个问题是您使用的模式。 " dd-MM-yyyy hh:mm:ss"可能不正确,因为它在1-12范围内使用半天的时钟小时,但缺少上午/下午的信息。使用更好的图案符号HH。查看webservice的文档以获取正确的格式。

答案 1 :(得分:0)

确保服务器和客户端计算机上的时钟同步。 6分钟可能只是两者之间的偏差。