Конвертировать метку времени NTP в utc
Какой самый простой способ преобразовать метку времени NTP в utc. Я знаю, что это в NTP, я могу преобразовать его в любой другой формат.
Благодарю. Боб.
3 ответа
Попробуйте что-нибудь подобное? Я не уверен в формате этих "секунд с 1 января 1900 года", но вы можете изменить, как считаете нужным.
long ntp = 3490905600;
DateTime start = new DateTime(1900, 1, 1);
DateTime dt = start.AddSeconds(ntp);
Console.WriteLine(dt.ToString());
Console.WriteLine(dt.ToUniversalTime().ToString());
Как указывал Рене, временная метка NTP состоит из целой и дробной частей. Целая часть представляет количество секунд с базового времени, которое составляет 1 января 1900 года. Дробная часть представляет количество дробных единиц (единица равна 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)(((Двойная) дробь / UInt32.MaxValue) * 1000);
Что 12 в этом случае.
Таким образом, значение DateTime получается из:
DateTime BaseDate = new DateTime (1900, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
DateTime dt = BaseDate.AddSeconds (секунд).AddMilliseconds(миллисекунд);
Поэтому временная метка NTP для 14236589681638796952 равна 14 января 2005 года в 17:58:59 и 12 миллисекунд UTC.
Это работает надежно, для меня:
#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 ;