简体   繁体   English

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

[英]Why UTC timezone giving ahead time for System.currentTimeMillis in Java?

I am getting current time from RubyOnRails webservice in Unix Timestamp format(ie. in seconds from 1 Jan 1970), the timezone on server is UTC . 我从UnixOnstamp格式的RubyOnRails Web服务获取当前时间(即,从1970年1月1日开始的秒数),服务器上的时区为UTC

In Java I am trying to convert local current time to UTC time . 在Java中,我试图将本地当前时间转换为UTC时间 But every time it is giving 6+ minutes ahead time. 但是每次它都会提前6分钟以上 I want to get the difference of UTC current time and the time returned from service. 我想获取UTC当前时间与服务返回时间之间的差额。 My Java code is - 我的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);

Where serverTime is the time I am getting from webservice. 其中serverTime是我从Web服务获取的时间。 And the value for resTime shows negative value which is approx 6+ minutes. 并且resTime的值显示为负值,大约为6分钟以上。

So my question is why UTC timezone giving ahead time for System.currentTimeMillis? 所以我的问题是,为什么UTC时区为System.currentTimeMillis提前了时间?

Please help me to resolve this issue. 请帮助我解决此问题。

In contrast to the assumption in a comment of of @JB Nizet the expressions sdf.getCalendar().getTimeInMillis() and System.currentTimeMillis() are not equivalent. 与@JB Nizet的注释中的假设相反,表达式sdf.getCalendar().getTimeInMillis()System.currentTimeMillis()不等效。 Proof: 证明:

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)));

Output: 输出:

date via System.currentTimeMillis()=2015-02-26T12:19:09
date via sdf.getCalendar()=1889-12-31T04:41:21

If you carefully study the source code of SimpleDateFormat and DateFormat you will find within the initialization part code like: 如果您仔细研究SimpleDateFormatDateFormat的源代码,则会在初始化部件代码中找到类似以下内容的代码:

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

The conclusion is to strictly avoid the method getCalendar() on your DateFormat -object. 结论是严格避免在 DateFormat -object上使用getCalendar()方法 It is only used as intermediate mutable object for internal format and parse processing. 它仅用作内部可变对象,用于内部格式和解析处理。 It is hard to say what you will really get as time this way. 很难说通过这种方式您将真正获得什么。 Instead use directly System.currentTimeMillis() to compare your local time with server time. 而是直接使用System.currentTimeMillis()将本地时间与服务器时间进行比较。

Another problem is the pattern you use. 另一个问题是您使用的模式。 "dd-MM-yyyy hh:mm:ss" is probably not correct because it uses the clock hour of half day in range 1-12 but the information for am/pm is missing. “ dd-MM-yyyy hh:mm:ss”可能不正确,因为它使用半天的时钟时间(范围1-12),但是缺少am / pm的信息。 Use better the pattern symbol HH. 最好使用图案符号HH。 Check the documentation of webservice for the right format. 检查Web服务的文档以获取正确的格式。

Make sure the the clock on the server and on the client machine are synchronized. 确保服务器和客户端计算机上的时钟同步。 The 6 minutes could simply be an offset between the two. 这6分钟可能只是两者之间的偏移。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM