我知道这是一个老问题,但我注意到所有答案都没有解释如何使用这些库。在这个答案中,我们将展示一个基本的实现及其背后的逻辑。
实现它的一种简单方法是使用Apache Commons Net 库。这个库将提供一个NTPUDPClient
类来管理无连接的 NTP 请求并返回一个TimeInfo
实例。此实例应计算系统时间和 NTP 服务器时间之间的偏移量。让我们尝试在这里实现它:
- 将Apache Commons Net 库添加到您的项目中。
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
- 创建
NTPUDPClient
该类的新实例。
- 设置默认超时和
InetAddress
NTP 服务器。
- 调用该
NTPUDPClient.getTime()
方法TimeInfo
从指定服务器检索具有时间信息的实例。
- 调用
computeDetails()
方法来计算和验证 NTP 消息包的详细信息。
- 最后,得到
offset
并计算一个原子时间。
这里我们有一个基本的实现:
import java.net.InetAddress;
import java.util.Date;
import org.apache.commons.net.ntp.NTPUDPClient;
import org.apache.commons.net.ntp.TimeInfo;
public class NTPClient {
private static final String SERVER_NAME = "pool.ntp.org";
private volatile TimeInfo timeInfo;
private volatile Long offset;
public static void main() throws Exception {
NTPUDPClient client = new NTPUDPClient();
// We want to timeout if a response takes longer than 10 seconds
client.setDefaultTimeout(10_000);
InetAddress inetAddress = InetAddress.getByName(SERVER_NAME);
TimeInfo timeInfo = client.getTime(inetAddress);
timeInfo.computeDetails();
if (timeInfo.getOffset() != null) {
this.timeInfo = timeInfo;
this.offset = timeInfo.getOffset();
}
// This system NTP time
TimeStamp systemNtpTime = TimeStamp.getCurrentTime();
System.out.println("System time:\t" + systemNtpTime + " " + systemNtpTime.toDateString());
// Calculate the remote server NTP time
long currentTime = System.currentTimeMillis();
TimeStamp atomicNtpTime = TimeStamp.getNtpTime(currentTime + offset).getTime()
System.out.println("Atomic time:\t" + atomicNtpTime + " " + atomicNtpTime.toDateString());
}
public boolean isComputed()
{
return timeInfo != null && offset != null;
}
}
你会得到类似的东西:
System time: dfaa2c15.2083126e Thu, Nov 29 2018 18:12:53.127
Atomic time: dfaa2c15.210624dd Thu, Nov 29 2018 18:12:53.129