2010-07-29 7 views
3

J'ai réussi à faire une demande NTP et récupérer l'heure du serveur de sa réponse NTP. Je veux convertir ce nombre en temps humain, en écrivant en C++. quelqu'un peut-il m'aider? comme exemple vous pouvez regarder: http://www.4webhelp.net/us/timestamp.php?action=stamp&stamp=771554255&timezone=0 une fois que vous définissez l'horodatage à 771554255 vous obtiendrez "29/7/2010 13:14:32". je veux faire la même chose dans mon code, toute aide?convertir heure NTP en temps humain

+1

Comme la première réponse mentionné, la page ne traite pas souligné avec horodatage NTP (64 bits, secondes + secondes fractions, à partir du 1er janvier 1900) mais avec un temps Unix (32 bits, secondes à partir du 1er janvier 1970) .Que voulez-vous? – pascal

+1

Comme une réponse éphémère (?) Mentionnée (avec un exemple Perl), il vous suffit de prendre les 32 premiers bits, de supprimer le nombre de secondes entre le 1er janvier 1900 et le 1er janvier 1970 (environ 70 * 365,25 * 24 * 3600), et vous avez un temps Unix() -compatible value ... – pascal

+1

Jus Pour vérifier, le bit 32 qui donne le nombre de secondes dans l'horodatage NTP a le bit de poids fort défini depuis 1968 ... donc, en tant qu'entier signé, il semble être négatif. – pascal

Répondre

3

Ce n'est pas C++, mais voici une implémentation de Perl. La conversion de ce en C++ devrait être pas grand-chose:

http://www.ntp.org/ntpfaq/NTP-s-related.htm#AEN6780

# usage: perl n2u.pl timestamp 
# timestamp is either decimal: [0-9]+.?[0-9]* 
# or hex: (0x)?[0-9]+.?(0x)?[0-9]* 

# Seconds between 1900-01-01 and 1970-01-01 
my $NTP2UNIX = (70 * 365 + 17) * 86400; 

my $timestamp = shift; 
die "Usage perl n2u.pl timestamp (with or without decimals)\n" 
    unless ($timestamp ne ""); 

my ($i, $f) = split(/\./, $timestamp, 2); 
$f ||= 0; 
if ($i =~ /^0x/) { 
    $i = oct($i); 
    $f = ($f =~ /^0x/) ? oct($f)/2 ** 32 : "0.$f"; 
} else { 
    $i = int($i); 
    $f = $timestamp - $i; 
} 

my $t = $i - $NTP2UNIX; 
while ($t < 0) { 
    $t += 65536.0 * 65536.0; 
} 

my ($year, $mon, $day, $h, $m, $s) = (gmtime($t))[5, 4, 3, 2, 1, 0]; 
$s += $f; 

printf("%d-%02d-%02d %02d:%02d:%06.3f\n", 
     $year + 1900, $mon+1, $day, $h, $m, $s); 
+0

J'ai hésité à poster ceci au début, parce que c'est perl, pas C++. Mais la méthode est correcte, et peut facilement être porté en C++. – NinjaCat

+0

Il me donne actuellement un moment dans les années 2080? – Stef

-1

Voici le code C++ pour vous .. mais ce ne l'est pas .. Les fenêtres api utilisé fait ici le nécessaire mais il y a un grand calcul mathématique derrière elle .. C'est une grande douleur à comprendre donc je ne l'ai pas mis ici. Pour la classe "CSNTPClient", vous devrez copier et coller l'en-tête "sntp.h" du contenu de l'URL ".htm"> http://read.pudn.com/downloads160/sourcecode/windows/comm/720007/SntpTest/Sntp .h_.htm ». Ceci est une version modifiée de l'exemple de code PJ Naughters .. et il y a u go ... Vive !!

#include "stdafx.h" 
int main() 
{ 
    //Initialise the winsock stack 
    WSADATA wsaData; 
    BYTE wsMajorVersion = 1; 
    BYTE wsMinorVersion = 1; 
    WORD wVersionRequested = MAKEWORD(wsMinorVersion, wsMajorVersion); 
    if (WSAStartup(wVersionRequested, &wsaData) != 0) 
    { 
     _tprintf(_T("Failed to load winsock stack\n")); 
     return 1; 
    } 
    if (LOBYTE(wsaData.wVersion) != wsMajorVersion || HIBYTE(wsaData.wVersion) != wsMinorVersion) 
    { 
     _tprintf(_T("Winsock stack does not support version which this program requires\n")); 
     WSACleanup(); 
     return 1; 
    } 

    //Do the actual NTP Query 
    CSNTPClient sntp; 
    NtpServerResponse response; 
    if (sntp.GetServerTime(specify ntp server url or ip, response)) 
    { 
     _tprintf(_T("Time was successfully retreived from NTP server\n")); 

     SYSTEMTIME st1 = response.m_OriginateTime; 
     SYSTEMTIME st2 = response.m_ReceiveTime; 
     SYSTEMTIME st3 = response.m_TransmitTime; 
     SYSTEMTIME st4 = response.m_DestinationTime; 

     cout << response.m_DestinationTime << endl; 

     TIME_ZONE_INFORMATION lpTimeZoneInfo; 
     GetTimeZoneInformation(&lpTimeZoneInfo); //Get the local TIME ZONE 
     SYSTEMTIME stLocal; 
     //To Get Local Time from the fetched GMT/UTC Time from the server, use SystemTimeToTzSpecificLocalTime() 
     //To get GMT/UTC Time from Local Time, use the API TzSpecificLocalTimeToSystemTime() 
     SystemTimeToTzSpecificLocalTime(&lpTimeZoneInfo, &st3, &stLocal); 

     _tprintf(_T("\n")); 
     _tprintf(_T("       DD/MM/YYYY HH:MM:SS.MS\n")); 
     _tprintf(_T("\n\n\nObtaining Time thru API SystemTimeToTzSpecificLocalTime :\n\n")); 
     _tprintf(_T("Server Transmit Date was %02d/%02d/%04d, %02d:%02d:%02d.%03d\n"), st3.wDay, st3.wMonth, st3.wYear, st3.wHour, st3.wMinute, st3.wSecond, st3.wMilliseconds); 
     _tprintf(_T("Client Destination Date was %02d/%02d/%04d, %02d:%02d:%02d.%03d\n"), stLocal.wDay, stLocal.wMonth, stLocal.wYear, stLocal.wHour, stLocal.wMinute, stLocal.wSecond, stLocal.wMilliseconds); 
    } 
} 
+0

Hey, une solution autonome et sa description serait mieux je pense. – Aldream

Questions connexes