当前位置:首页 > 开发 > 编程语言 > Java > 正文

Java获取网络时间

发表于: 2013-04-02   作者:BrokenDreams   来源:转载   浏览次数:
摘要:        最近项目中涉及到一个时间验证的问题,需要根据当前时间来验证业务数据是否过期。所以直接写代码如下: new java.util.Date().getTime();         结果测试的时候出现了问题,怎么验证都是过期。后来发现是服务
       最近项目中涉及到一个时间验证的问题,需要根据当前时间来验证业务数据是否过期。所以直接写代码如下:
new java.util.Date().getTime();


        结果测试的时候出现了问题,怎么验证都是过期。后来发现是服务器主机时间不对。也就是说如果服务器时间不准确或者被篡改,那么验证这部分会出现问题。所以决定采用获取 网络当前时间来代替获取 系统当前时间
        搜索了一下,原来获取网络时间有一个协议: Network Time Protocol(NTP: 网络时间协议 )。
        协议有了,那么java有没有相关实现呢。当然也有了。apache的commons-net包下面有ntp的实现。主要的类是:
org.apache.commons.net.ntp.NTPUDPClient


org.apache.commons.net.ntp.TimeInfo

看下用法,NTPUDPClient中有方法:
public TimeInfo getTime(InetAddress host, int port) throws IOException


public TimeInfo getTime(InetAddress host) throws IOException

第二个重载方法是用协议规范默认端口:123。

看下具体实现代码:
/***
     * Retrieves the time information from the specified server and port and
     * returns it. The time is the number of miliiseconds since
     * 00:00 (midnight) 1 January 1900 UTC, as specified by RFC 1305.
     * This method reads the raw NTP packet and constructs a <i>TimeInfo</i>
     * object that allows access to all the fields of the NTP message header.
     * <p>
     * @param host The address of the server.
     * @param port The port of the service.
     * @return The time value retrieved from the server.
     * @exception IOException If an error occurs while retrieving the time.
     ***/
    public TimeInfo getTime(InetAddress host, int port) throws IOException
    {
        // if not connected then open to next available UDP port
        if (!isOpen())
        {
            open();
        }

        NtpV3Packet message = new NtpV3Impl();
        message.setMode(NtpV3Packet.MODE_CLIENT);
        message.setVersion(_version);
        DatagramPacket sendPacket = message.getDatagramPacket();
        sendPacket.setAddress(host);
        sendPacket.setPort(port);

        NtpV3Packet recMessage = new NtpV3Impl();
        DatagramPacket receivePacket = recMessage.getDatagramPacket();

        /*
         * Must minimize the time between getting the current time,
         * timestamping the packet, and sending it out which
         * introduces an error in the delay time.
         * No extraneous logging and initializations here !!!
         */
        TimeStamp now = TimeStamp.getCurrentTime();

        // Note that if you do not set the transmit time field then originating time
        // in server response is all 0's which is "Thu Feb 07 01:28:16 EST 2036".
        message.setTransmitTime(now);

        _socket_.send(sendPacket);
        _socket_.receive(receivePacket);

        long returnTime = System.currentTimeMillis();
        // create TimeInfo message container but don't pre-compute the details yet
        TimeInfo info = new TimeInfo(recMessage, returnTime, false);

        return info;
    }

       大概过程就是想目标网络地址发包来获取网络时间,具体细节由协议来规范。
所以我们还需要来确定网络地址,继续搜索,发现网络上有时间服务器,也叫授时服务器。我们的用智能手机的时间是不是通过这种方式来同步的呢?
       找到了这样一些服务器地址:
中国时间网
       国外的
NIST Internet Time Servers

代码例子:
	public static void main(String[] args) {
		try {
			NTPUDPClient timeClient = new NTPUDPClient();
			String timeServerUrl = "time-a.nist.gov";
			InetAddress timeServerAddress = InetAddress.getByName(timeServerUrl);
			TimeInfo timeInfo = timeClient.getTime(timeServerAddress);
			TimeStamp timeStamp = timeInfo.getMessage().getTransmitTimeStamp();
			DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
			System.out.println(dateFormat.format(timeStamp.getDate()));
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}


输出:
2013-04-02 11:01:08


可调整本机时间,然后观察输出是否正确。

Java获取网络时间

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
SimpleDateFormat:主要是日期格式、参数确认 SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM
  今天在公司的cocos2dx项目中遇到一个需求,需要获取网络时间和系统时间对比,目的是防止用户更
1、环境: OS:Windows 7 64bit Java:j2sdk1.4.2_07 <div style="font: 14px/22px Tahoma, 'Mic
我有的时候写程序要用到当前时间,我就想用python去取当前的时间,虽然不是很难,但是老是忘记,用
方法一:使用data与time函数 方法二:设置默认时区,访止出错 特别说明 就是echo date("y-m-dh:i:s",ti
今天在开发项目的时候遇到一个问题就是怎么获取当前时间的前一天和后一天,这个实现的逻辑并不复杂
今天在开发项目的时候遇到一个问题就是怎么获取当前时间的前一天和后一天,这个实现的逻辑并不复杂
PHP提供了多种获取时间和日期的函数,除了通过time()函数获取当前的UNIX时间戳外,调用getdate()函
一。 iReport 中获取系统当前时间 1,选择TextField类型为 java.util.Date 2,在pattern中 点 在Dat
一。 iReport 中获取系统当前时间 1,选择TextField类型为 java.util.Date 2,在pattern中 点 在Dat
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号