我正在尝试构建一个示例应用程序,它将显示一个概念验证,以便将时间与符合RFC 868的时间服务器同步。
到目前为止,使用Java Socket API,我能够连接和查询服务器并从服务器获得响应,但它不是人类可读的格式。
我得到的回应是:�)6
我认为响应是二进制格式的(尽管不确定)。 RFC 868说Send the time as a 32 bit binary number
。
我的问题是: 1)如何解析此响应? 2)除了我的这种方法之外,我想知道是否还有其他推荐的方法来实现这一点。
提前致谢。
答案 0 :(得分:2)
1)如何解析此响应?
从Apache Commons Net库中查看source code of TimeTCPClient:
public long getTime() throws IOException {
DataInputStream input;
input = new DataInputStream(_input_);
return (input.readInt() & 0xffffffffL);
}
public Date getDate() throws IOException {
return new Date((getTime() - SECONDS_1900_TO_1970)*1000L);
}
2)除了我的这种方法之外,我想知道是否还有其他推荐方法可以实现这一目标。
使用Apache Commons Net Library,查看API of TimeTCPClient。
Apache Commons Net home page,希望这有帮助。
答案 1 :(得分:2)
如RFC中所述,这是自1900-01-01T00:00:00以来的秒数。对于Java将其转换为Long,将基准日期更改为1970-01-01T00:00:00,并乘以1000以获取日期。然后,您可以使用此值创建新日期。
将套接字输入流包装到DataInputStream并读入rfsOffset(我使用常量)。然后你可以做类似的事情:
int rfcOffset = -752253627; // Fri Apr 06 11:00:32 EDT 2012
// Current offsets will be negative convert to long positive value
long offsetSecs = rfcOffset + 4294967296L;
System.out.println(offsetSecs);
// Adjust time base from 1900 to 1970 and convert to millis
long offsetMillis = ( offsetSecs - 2208988800L)* 1000L;
System.out.println(offsetMillis);
Date rfcDate = new Date(offsetMillis);
System.out.println(rfcDate.toString());
注意:这仅适用于2036年,时间将关闭几毫秒。
编辑:RFC 868是一种旧协议,不再被认为是同步的好时间源。 NTP是一个很好的时间源,并将返回正确的秒。它可能会在几毫秒内消失,但通常精确到10毫秒。许多硬件时钟漂移很明显,我看到时钟不准确的系统出现了明显的漂移(即使NTP运行().NTP将纠正漂移时钟,但需要几分钟来确定所需的移位。
EDIT2:虽然RFC 868已经过时,但可以将手机上的时间设置为最接近的秒数,而无需后台处理。如果您的手机可以同步到您的提供商发送的信号,则不需要这样做。