如何获得游戏的实时时间

时间:2014-12-22 14:33:15

标签: java time ntp

我正在使用Java,我正在制作游戏。在这个游戏中,实时是非常重要的一部分。 出于这个原因,我试图使用Ntp获得实时。

我在网上找到的是这段代码。

import java.net.InetAddress;
import java.util.Date;
import org.apache.commons.net.ntp.NTPUDPClient; 
import org.apache.commons.net.ntp.TimeInfo;

public class test{
    public static void main(String args[]) throws Exception{
        String TIME_SERVER = "time-a.nist.gov";   
        NTPUDPClient timeClient = new NTPUDPClient();
        InetAddress inetAddress = InetAddress.getByName(TIME_SERVER);
        TimeInfo timeInfo = timeClient.getTime(inetAddress);

        long returnTime = timeInfo.getReturnTime();
        Date time = new Date(returnTime);

        System.out.println("Time from " + TIME_SERVER + ": " + time);
    }
}

我的问题是使用这个,系统仍然得到System.currentMillis();因为它实际上会打印出本地机器获取时间消息的时间。因此,如果玩家将桌面时间改为未来,游戏时间也会发生变化。

如果有人可以提供实时帮助,我会非常感激。 附:我没有服务器,我的游戏将在Kongregate上播放,数据将在播放器计算机上播放。

提前致谢。

3 个答案:

答案 0 :(得分:5)

只需在程序开始时通过NTP获取一次,然后使用System.nanoTime()获取之后的相对时间。它完全是单调的,不会通过设置系统时间来改变。

答案 1 :(得分:3)

根据NTPUDPClient javadoc:

  

要使用该类,只需打开一个打开的本地数据报套接字并调用getTime()来检索时间。然后调用close以正确关闭连接。允许连续调用getTime而无需重新建立连接。

您在代码中错过了对open()的来电(技术上close()),但这不是您发出问题的原因。

此外,在您的要求中,您声明您需要实时(而不是本地客户端可以设置的任何时间)。此数量不应直接获得,而应作为通过方法getOffset()获得的本地时间与服务器(远程)时间匹配所需的偏移量。

如果获得实时是一个常见的过程,您可能只想在开始时使用NTP一次,并使用获得的偏移来纠正未来的系统时间,从而减少实时检索时的延迟。

这样的过程可以在类中描述:

public class TimeKeeper{
    // Constant: Time Server
    private final String TIME_SERVER = "time-a.nist.gov";

    // Last time the time offset was retrieved via NTP
    private long last_offset_time = -1;

    // The real time, calculated from offsets, of when the last resync happened
    private long retrieve_time;

    private synchronized void resync(){
        NTPUDPClient timeClient = new NTPUDPClient();
        InetAddress inetAddress = InetAddress.getByName(TIME_SERVER);
        TimeInfo timeInfo = null;

        try{
            timeClient.open();
            timeInfo = timeClient.getTime(inetAddress);
        }catch(IOException ex){
            return;
        }finally{
            timeClient.close();
        }

        // Real time calculated from the offset time and the current system time.
        retrieve_time = System.currentTimeMillis() + timeInfo.getOffset();
        last_offset_time = System.nanoTime();
    }

    public long getRealTimeInMillis(){
        // Possible to set some resync criteria here
        if(last_offset_time == -1){
            resync();

            // Handle exception whilst retrieving time here
        }

        // Returns the system time, corrected with the offset
        return retrieve_time + Math.round((System.nanoTime() - last_offset_time) / 1000.0)
    }
}

答案 2 :(得分:2)

试试这个:

String TIME_SERVER = "time-a.nist.gov";   
TimeTCPClient client = new TimeTCPClient();

try {
    client.connect(TIME_SERVER);
    System.out.println(client.getDate());
} finally {
    client.disconnect();
}