First, let's understand the formats:
- A NTP timestamp consists of a 32-bit part for second and a 32-bit part for fraction second. And the unit of the fraction part is 2-32 second.
- A UNIX Struct timeval consists of a 32-bit part for second and a 32-bit part for micro-second.
Second, let's see the meaning of NTP timestamp and UNIX struct timeval
- A NTP timestamp is defined as the number of seconds have elapsed since Jan 1, 1900.
- A UNIX struct timeval is defined as the number of seconds have elapsed since Jan 1, 1970.
Assume the structure of NTP is
struct ntp_time_t {
uint32_t second;
uint32_t fraction;
};
And the knowned timeval structure of UNIX is
struct timeval {
uint32_t tv_sec;
uint32_t tv_usec;
};
To convert from NTP timestamp to UNIX timeval, we need to offset the second field and
transform the fraction part:
void convert_ntp_time_into_unix_time(struct ntp_time_t *ntp, struct timeval *unix)
{
unix->tv_sec = ntp->second - 0x83AA7E80; // the seconds from Jan 1, 1900 to Jan 1, 1970
unix->tv_usec = (uint32_t)( (double)ntp->fraction * 1.0e6 / (double)(1LL<<32) );
}
void convert_unix_time_into_ntp_time(struct timeval *unix, struct ntp_time_t *ntp)
{
ntp->second = unix->tv_sec + 0x83AA7E80;
ntp->fraction = (uint32_t)( (double)(unix->tv_usec+1) * (double)(1LL<<32) * 1.0e-6 );
}
Example:
#include <sys/time.h>
#include <stdio.h>
#include <stdint.h>
struct ntp_time_t {
uint32_t second;
uint32_t fraction;
};
void convert_ntp_time_into_unix_time(struct ntp_time_t *ntp, struct timeval *unix)
{
unix->tv_sec = ntp->second - 0x83AA7E80; // the seconds from Jan 1, 1900 to Jan 1, 1970
unix->tv_usec = (uint32_t)( (double)ntp->fraction * 1.0e6 / (double)(1LL<<32) );
}
void convert_unix_time_into_ntp_time(struct timeval *unix, struct ntp_time_t *ntp)
{
ntp->second = unix->tv_sec + 0x83AA7E80;
ntp->fraction = (uint32_t)( (double)(unix->tv_usec+1) * (double)(1LL<<32) * 1.0e-6 );
}
int main()
{
struct ntp_time_t ntp;
struct timeval unix;
// get time unix time via gettimeofday
gettimeofday(&unix, NULL);
printf("UNIX Time: %ld %ld\n", unix.tv_sec, unix.tv_usec);
// convert unix time to ntp time
convert_unix_time_into_ntp_time(&unix, &ntp);
printf("NTP Time: %ld %ld\n", ntp.second, ntp.fraction);
// convert ntp time back to unix time to see whether they are same
convert_ntp_time_into_unix_time(&ntp, &unix);
printf("UNIX Time: %ld %ld\n", unix.tv_sec, unix.tv_usec);
}
Output:
UNIX Time: 1340097242 933680
NTP Time: 3549086042 4010129359
UNIX Time: 1340097242 933680