将NTP时间戳转换为utc

时间:2011-03-05 21:21:50

标签: c#-4.0 ntp

什么是将NTP时间戳转换为utc的最简单方法。我知道它在NTP中,我可以将其转换为任何其他格式。

感谢。  鲍勃。

3 个答案:

答案 0 :(得分:18)

正如rene指出的那样,NTP时间戳由一个整数和一个小数部分组成。整数部分表示自基准时间以来的秒数,即1900年1月1日。小数部分表示小数单位的数量(单位为1 /((2 ^ 32)-1))。

此外,时间表示为UTC。

因此,如果您的NTP时间戳为14236589681638796952.NTP是64位无符号定点数。我们可以说:

  

UInt64 ntpTimestamp = 14236589681638796952;

高32位由下式给出:

  

UInt32秒=(UInt32)((ntpTimestamp>> 32)& 0xFFFFFFFF);

低32位由下式给出:

  

UInt32分数=(UInt32)(ntpTimestamp& 0xFFFFFFFF);

以秒为单位的数字等于最重要的单词或在这种情况下: 秒== 3314714339

使用此计算可以从分数计算毫秒数:

  

Int32毫秒=(Int32)(((Double)fraction / UInt32.MaxValue)* 1000);

在这种情况下,这是12。

因此,DateTime值来自:

  

DateTime BaseDate = new DateTime(1900,1,1,0,0,0,0,DateTimeKind.Utc);

     

DateTime dt = BaseDate.AddSeconds(seconds).AddMilliseconds(milliseconds);

因此,NTP时间戳14236589681638796952等于2005年1月14日17:58:59和12毫秒UTC。

答案 1 :(得分:2)

对我来说,这是可靠的:

#define NTP_TIMESTAMP_DIFF     (2208988800)    // 1900 to 1970 in seconds
#define NTP_MAX_INT_AS_DOUBLE  (4294967295.0)  // Max value of frac

  // take care of the endianness
  reply_pkt.tx_time_sec = ntohl( reply_pkt.tx_time_sec ) ;
  reply_pkt.tx_time_frac = ntohl( reply_pkt.tx_time_frac ) ;
  // parse
  time_t tx_time = ( time_t ) ( reply_pkt.tx_time_sec - NTP_TIMESTAMP_DIFF );
  double frac = ((double)reply_pkt.tx_time_frac) / NTP_MAX_INT_AS_DOUBLE ; // 2^32 -1

  struct tm *tm = gmtime(&tx_time) ;
  char ts[49];
  strftime(ts,48,"[%Y-%m-%d %H:%M:%S]",tm);
  printf("NTP query: reply was %s\n",ts);

  ntp_time_seconds = ((double)tx_time) + frac ;

答案 2 :(得分:0)

尝试这样的事情?我不确定1900年1月1日以来'秒的格式',但你可以根据需要进行修改。

long ntp = 3490905600; 
DateTime start = new DateTime(1900, 1, 1);
DateTime dt = start.AddSeconds(ntp);

Console.WriteLine(dt.ToString());
Console.WriteLine(dt.ToUniversalTime().ToString());