diff options
Diffstat (limited to 'libntp/calyearstart.c')
-rw-r--r-- | libntp/calyearstart.c | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/libntp/calyearstart.c b/libntp/calyearstart.c index 0f7ca4f9d065..c5a63f729b39 100644 --- a/libntp/calyearstart.c +++ b/libntp/calyearstart.c @@ -7,16 +7,50 @@ #include "ntp_types.h" #include "ntp_calendar.h" #include "ntp_stdlib.h" +#include "ntp_assert.h" +/* + * Juergen Perlinger, 2008-11-12 + * Use the result of 'caljulian' to get the delta from the time stamp to the + * beginning of the year. Do not make a second trip through 'caltontp' after + * fixing the date, apart for invariant tests. + */ u_long calyearstart(u_long ntp_time) { - struct calendar jt; + struct calendar jt; + ntp_u_int32_t delta; + + caljulian(ntp_time,&jt); + + /* + * Now we have days since yearstart (unity-based) and the time in that + * day. Simply merge these together to seconds and subtract that from + * input time. That's faster than going through the calendar stuff + * again... + */ + delta = (ntp_u_int32_t)jt.yearday * SECSPERDAY + + (ntp_u_int32_t)jt.hour * MINSPERHR * SECSPERMIN + + (ntp_u_int32_t)jt.minute * SECSPERMIN + + (ntp_u_int32_t)jt.second + - SECSPERDAY; /* yearday is unity-based... */ + +# if ISC_CHECK_INVARIANT + /* + * check that this computes properly: do a roundtrip! That's the only + * sensible test here, but it's a rather expensive invariant... + */ + jt.yearday = 0; + jt.month = 1; + jt.monthday = 1; + jt.hour = 0; + jt.minute = 0; + jt.second = 0; + NTP_INVARIANT((ntp_u_int32_t)(caltontp(&jt) + delta) == (ntp_u_int32_t)ntp_time); +# endif - caljulian(ntp_time,&jt); - jt.yearday = 1; - jt.monthday = 1; - jt.month = 1; - jt.hour = jt.minute = jt.second = 0; - return caltontp(&jt); + /* The NTP time stamps (l_fp) count seconds unsigned mod 2**32, so we + * have to calculate this in the proper way! + */ + return (ntp_u_int32_t)(ntp_time - delta); } |