获取网络时间

这两天有一个应用需要获取网络时间,虽然一直知道可以从时间服务器获取时间,却从来也没有操作过,借这个机会重新进行一下深入了了解。

基本的思路就是:通过SOCKET连接时间服务器,直接接收从服务器发送的过来的时间数据。

void GetNetTime()
{
    TIME_ZONE_INFORMATION tzinfo;
    DWORD dwStandardDaylight;
    int nRet;

    /* Get server IP */
    struct hostent *host;
    char *pServerIP;

    host = gethostbyname("time.nist.gov");
    if (NULL == host)
    {
        return;
    }

    pServerIP = inet_ntoa(*(struct in_addr*)host->h_addr_list[0]);

    /* Connect to time server, and get time */
	WORD wVersionRequested;
	WSADATA wsaData;
	int nErrCode;
    SOCKET sockfd;

	wVersionRequested = MAKEWORD(2, 2);
	nErrCode = WSAStartup(wVersionRequested, &wsaData);
    if (0 != nErrCode)
    {
        return;
    }

    char cTimeBuf[40] = { 0 };
    unsigned long ulTime = 0;

    do
    {
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (INVALID_SOCKET == sockfd)
        {
            continue;
        }

        int TimeOut = 3000;//设置接收超时6秒
        if(::setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&TimeOut,sizeof(TimeOut)) == SOCKET_ERROR)
        {
            return;
        }

	    sockaddr_in	addr;

	    memset(&addr, 0, sizeof(addr));
	    addr.sin_family         = AF_INET;
	    addr.sin_port           = htons(37);
	    addr.sin_addr.s_addr    = inet_addr(pServerIP);

        nRet = connect(sockfd, (sockaddr *)&addr, sizeof(addr));
	    if (SOCKET_ERROR == nRet)
	    {
            continue;
	    }

        nRet = recv(sockfd, (char *)&ulTime, sizeof(ulTime), 0);
        if ((SOCKET_ERROR != nRet) && (0 != nRet))
        {
            break;
        }

        closesocket(sockfd);
    } while (1);

    closesocket(sockfd);

    /* 到时为止,获取到的只是网络序的4个字节时间数据,
       需要先转换成本地字节序,然后再通过ConvertTime函数转换成可以识别的字符串。
    */
    unsigned long ulTimehl = ntohl(ulTime);
    ConvertTime(ulTimehl);

    return;
}
void ConvertTime(unsigned long ulTime)
{
    // Windows文件时间是一个64位的值,它是从1601年1月1日中午12:00到现在的时间间隔,
    // 单位是1/10,000,000秒,即1000万分之1秒(100-nanosecond)
    FILETIME ft;
    SYSTEMTIME st;

    // 首先将基准时间(1900年1月1日0点0分0秒0毫秒)转化为Windows文件时间
    st.wYear = 1900;
    st.wMonth = 1;
    st.wDay = 1;
    st.wHour = 0;
    st.wMinute = 0;
    st.wSecond = 0;
    st.wMilliseconds = 0;

    SystemTimeToFileTime(&st, &ft);

    // 然后将Time Protocol使用的基准时间加上逝去的时间(ulTime)
    LONGLONG *pLLong = (LONGLONG *)&ft;

    /* 注意:
       文件时间单位是1/1000 0000秒(即100ns),
       需要将从时间服务器上获取的以秒为单位的ulTime做一下转换
    */
    *pLLong += (LONGLONG) 10000000 * ulTime;

    // 再将时间转化回来,更新系统时间
    FileTimeToSystemTime(&ft, &st);

    TRACE(_T("%04d%02d%02d %02d:%02d:%02d\n"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond );

    return;
}

各地时差都不一致,可以根据GetTimeDiff函数计算当地时差,对上面的时间加以调整:

void GetTimeDiff()
{
    float bias;
    long sminute,shour;

    /* 获取时区信息 */
    dwStandardDaylight = GetTimeZoneInformation(&tzinfo); //获取时区与UTC的时间差 应该返回-8
    if (dwStandardDaylight == TIME_ZONE_ID_INVALID) //函数执行失败
    {
        return;
    }

    /* 时差调整 */
    bias = tzinfo.Bias;
    if (dwStandardDaylight == TIME_ZONE_ID_STANDARD) //标准时间有效
        bias += tzinfo.StandardBias;

    if (dwStandardDaylight == TIME_ZONE_ID_DAYLIGHT) //夏令时间
        bias += tzinfo.DaylightBias;

    shour   = bias / 60;
    sminute = fmod(bias, (float)60);
}

时间: 2024-10-08 04:38:24

获取网络时间的相关文章

cocos2dx获取网络时间(一)

今天在公司的cocos2dx项目中遇到一个需求,需要获取网络时间和系统时间对比,目的是防止用户更改系统时间进行某些非法操作 . 那么cocos2dx怎么来获取网络时间呢 ?我整理的思路如下: (1)由一个web api可以返回当前的网络时间 (2)cocos2dx通过http请求该api获取数据到本地 (3)cocos2dx解析数据得到当前的网络时间 一:首先就需要一个web接口来提供网络时间的数据,我在这里自己搭建一个WCF服务返回需要的数据. 新建WCF服务应用程序 , 项目命名为NetTi

.net 获取网络时间(北京时间)24小时制

/// <summary> /// 更新系统时间 /// </summary> public class UpdateTime { //设置系统时间的API函数 [DllImport("kernel32.dll")] private static extern bool SetLocalTime(ref SYSTEMTIME time); [StructLayout(LayoutKind.Sequential)] private struct SYSTEMTIM

实时获取网络时间 并转换为北京时间的函数

unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,Winapi.msxml, System.DateUtils, Vcl.StdCtrls; type TForm1 = class(TForm) Button1: TButton

多方法获取网络时间

转自:http://blog.csdn.net/xiaoxian8023/article/details/7250385 在做YH维护的时候,偶尔会碰到这样的问题:电脑的非正常关机导致系统时间出错(变为了2002-1-1),从而影响到项目系统的使用.尤其是设计到money的系统,如果时间错误,可能会导致无法想象的后果.所以我们可能需要用系统和网络的双重验证. 通过收集.修改.优化和测试,剔除了一些错误的和速度超慢的,只剩下了4种可行的方案.这些方案中主要有3类: 一.通过向某网站发送请求,获取服

cocos2dx获取网络时间(二):浅析CCHttpClient

在上一篇文章cocos2dx获取网络时间(一)中,我们使用CCHttpClient进行网络时间的数据请求和使用rapidjson解析Http请求得到的json数据 .在文章的最后 ,我留下了一个问题,怎么封装一个类来实现我们的方法. 新建一个c++类 ,命名为NetTime,继承自CCNode并重写init()方法.然后引入CCHttpClient和rapidjson需要的头文件.我们的需求是可以返回NetTime的年,月,日,小时,分和秒,分别定义它们的private字段和public方法:

iOS获取网络时间与转换格式

[NSDate date]可以获取系统时间,但是会造成一个问题,用户可以自己修改手机系统时间,所以有时候需要用网络时间而不用系统时间.获取网络标准时间的方法: 1.先在需要的地方实现下面的代码,创建一个URL并且连接 1 NSURL *url=[NSURL URLWithString:@"http://www.baidu.com"]; 2 NSURLRequest *request=[NSURLRequest requestWithURL:url]; 3 NSURLConnection

获取网络时间失败,求大神指点

private void GainTime() { new Thread(new Runnable() { @Override public void run() { try { URL url=new URL("http://www.taobao.com"); URLConnection uc=url.openConnection(); uc.connect(); long id=uc.getDate(); Date date=new Date(id); SimpleDateForm

c#获取网络时间并同步本地时间

通过TCP形式来获取NTP时间.主要代码如下: [DllImport("kernel32.dll")] private static extern bool SetLocalTime(ref Systemtime time); [StructLayout(LayoutKind.Sequential)] private struct Systemtime { public short year; public short month; public short dayOfWeek; pu

使用NTP获取网络时间-----java

在做系统对时的时候,需要使用到ntp来获取时间. 可以使用common-net包来获取ntp服务器的时间(即可以向那些标准时间服务器对时,也可以向自己设置好的ntp服务器进行对时). 使用java获取ntp的时间(t1,t2,t3,t4).下面是官网上给出的关于使用common-net关于ntp部分的使用例子. 很详细,很有帮助. 1 public class test { 2 3 private static final NumberFormat numberFormat = new java