2016-05-28 30 views
-2

C++のウィンドウで最も正確なUTC時刻を取得する最良の方法は何ですか?有効なUTC時刻を取得するC++

私はUTCタイムスタンプを含むサンプルを収集しています。サンプルが1時間以上経過していない場合は検証する必要があります。私はシステム時間を使用していますが、誰かが手動で変更する場合はどうなりますか?代わりにいくつかのWebサービスを使うべきですか?もしそうなら、どちらをお勧めしますか?

+1

管理者のみシステムクロックを手動で変更できます。 Windowsは、リモートタイムサーバーとクロックを同期するように構成できます。クロックが調整されるたびに、アプリケーションに通知がブロードキャストされます。 –

+1

これはあなたが心配する必要があるものではありません。ユーザーがシステム時刻を変更できる場合は、既にシステムを起動しているので、アプリのゲームオーバーです。 [彼らはすでに気密な廊下の反対側にあります](https://blogs.msdn.microsoft.com/oldnewthing/20160107-00/?p=92801)、つまり、たとえばバイナリにパッチを当てることができます最初にタイムチェックが発生しないようにします。ちょうどシステム時間を照会してください。 –

答えて

2

時刻が正しいことを確認したい場合は、NTPサーバーを照会することをお勧めします。 Windows C++の実装については、コードサンプルhereおよびhereを参照してください。

+0

それは私が探していたものです。どうもありがとう! –

+1

...ただし、インターネットに直接接続していないと動作しません。それが問題かどうかは、シナリオによって異なります。あなたのアプリケーションがすでに直接インターネットにアクセスしている場合は、おそらく問題ではありません。 –

0

あなたのリンクのための感謝のトンPlooij。 以下は私にとってはうまくいったコードを共有したいと思います。 両方の関数は、ナノ秒単位のUTC時間を提供します。 最初はシステム時刻に基づいていますが、2番目の時刻はNTPサーバー時刻にクエリを実行します。

#include <winsock2.h> 
#include <WS2tcpip.h> 

#include <stdio.h> 
#include <time.h> 

time_t getTimeLocal() 
{ 
    return 1000000000 * time(NULL); 
} 

time_t getTimeRemote() 
{ 
    struct sockaddr_in server_addr; 
    memset(&server_addr, 0, sizeof(server_addr)); 
    server_addr.sin_family = AF_INET; 
    server_addr.sin_addr.s_addr = inet_addr("200.20.186.76"); 
    server_addr.sin_port = htons(123); 

    protoent *proto = getprotobyname("udp"); 
    int s = socket(PF_INET, SOCK_DGRAM, proto->p_proto); 

    char msg[48] = { 0x08, 0, 0, 0, 0, 0, 0, 0, 0 }; 
    sendto(s, msg, sizeof(msg), 0, (struct sockaddr *) &server_addr, sizeof(server_addr)); 

    memset(msg, 0, sizeof(msg)); 
    struct sockaddr saddr; 
    socklen_t saddr_l = sizeof(saddr); 
    recvfrom(s, msg, 48, 0, &saddr, &saddr_l); 

    closesocket(s); 

    time_t rawtime = ntohl(*(u_long *) &msg[40]) - 2208988800U; 
    return 1000000000 * rawtime; 
} 

int main() 
{ 
    WSADATA wsaData; 
    WSAStartup(MAKEWORD(2, 2), &wsaData); 

    printf("UTC time:\n"); 
    printf("system: %llu [nsec]\n", getTimeLocal()); 
    printf("server: %llu [nsec]\n", getTimeRemote()); 

    WSACleanup(); 
    getchar(); 
    return 0; 
} 
+0

あなたは「*最も正確な* UTC時間を取得する最良の方法は何ですか?」と尋ねました。それはあなたが1時間以上を検出する必要があるだけだが、他の誰かがこれを読んでいる場合には問題はないようだ。上記のソケットコードを使ってntpサーバーを読むと、時間プロトコルの一部がネットワーク待ち時間の分析であるため、適切に構成されたWindowsマシンです。あなたの待ち時間は、トラフィックと帯域幅に応じて、数ミリ秒〜数秒です。もう1つのこと - IPアドレスをハードコーディングすると、コードがサーバーの障害を受けやすくなります。 –

+0

あなたのヒントをありがとう。あなたは正しいです、ハードコーディングIPは実際のアプリケーションのための悪い考えですが、上記の例では十分に保つのは明らかです。そして、精度と同じ - 上記の例から、私は応答を最大500ミリ秒待つためにソケット設定を削除しました。これはこれをかなり正確にしています。私のWindowsでは現在の時刻との差が+/- 30またはそれ以上になっているため、アプリケーションでは全く役に立たなくなってしまいます。そこで、このような違いを最大5秒間受け入れることができます。 –

+1

私はそれを見て、あなたは正しいです。 Windowsは、高解像度の時間同期を行うようには設計されていません。サードパーティのソリューションが必要です。 http://stackoverflow.com/questions/27253216/configure-windows-time-with-high-sub-seconds-precision –

関連する問題