Dave Hart wrote:
On Tue, Sep 28, 2010 at 12:40 UTC, Matt Davis<[email protected]> wrote:
I am having some trouble converting a POSIX UTC timestamp into a NTP timestamp.
The former being from the epoch starting January 1, 1970 at 12AM and the latter
being that of January 1 1900 12AM.
In summary my equation is this:
/* Seconds between 1970 and 1900 (with 17 leap years) */
uint64_t epoch_difference = (365 + 17) * 24 * 60 * 60;
As noted, this is just wrong.
Even if you fix it as suggested ((365*70+17)*86400) you still have a big
problem:
Even though you are assigning the result to a 64-bit unsigned int, the
actual calculation will probably take place within 32-bit signed
arithmetic, in which case it will overflow into a negative value.
You have to make sure that the constant calculation is handled with
64-bit int or at least 32-bit unsigned:
uint64_t epoch_difference = ((uint64_t)365*70 + 17) * (24 * 60 * 60);
uint64_t ntp_timestamp = (time(NULL) - epoch_difference)<< 32;
Unfortunately, when I interpret this value, I keep getting values in 2036. Â I
know my version of time() is from the 1970 epoch. Â So I am a tad confused here.
As was said on irc.freenode.net #ntp in response to your question
there, you are subtracting when you should be adding. There are more
seconds between now and 1900 than between now and 1970. The NTP
reference implementation has this code ready for you to use verbatim,
liberally licensed. See include/unixtime.h and libntp/systime.c,
particularly get_systime(). Note in particular that the reference
implementation disagrees with your code on the value of
epoch_difference (referred to as JAN_1970 in the NTP code):
#define JAN_1970 0x83aa7e80 /* 2208988800 1970 - 1900 in seconds */
Notice also that this 32-bit value has the sign bit set, i.e. it must be
handled as uint32_t or wider.
Terje
--
- <Terje.Mathisen at tmsw.no>
"almost all programming can be viewed as an exercise in caching"
_______________________________________________
questions mailing list
[email protected]
http://lists.ntp.org/listinfo/questions