1 /* $NetBSD: calyearstart.c,v 1.1.1.1 2009/12/13 16:55:02 kardel Exp $ */ 2 3 /* 4 * calyearstart - determine the NTP time at midnight of January 1 in 5 * the year of the given date. 6 */ 7 #include <sys/types.h> 8 9 #include "ntp_types.h" 10 #include "ntp_calendar.h" 11 #include "ntp_stdlib.h" 12 #include "ntp_assert.h" 13 14 /* 15 * Juergen Perlinger, 2008-11-12 16 * Use the result of 'caljulian' to get the delta from the time stamp to the 17 * beginning of the year. Do not make a second trip through 'caltontp' after 18 * fixing the date, apart for invariant tests. 19 */ 20 u_long 21 calyearstart(u_long ntp_time) 22 { 23 struct calendar jt; 24 ntp_u_int32_t delta; 25 26 caljulian(ntp_time,&jt); 27 28 /* 29 * Now we have days since yearstart (unity-based) and the time in that 30 * day. Simply merge these together to seconds and subtract that from 31 * input time. That's faster than going through the calendar stuff 32 * again... 33 */ 34 delta = (ntp_u_int32_t)jt.yearday * SECSPERDAY 35 + (ntp_u_int32_t)jt.hour * MINSPERHR * SECSPERMIN 36 + (ntp_u_int32_t)jt.minute * SECSPERMIN 37 + (ntp_u_int32_t)jt.second 38 - SECSPERDAY; /* yearday is unity-based... */ 39 40 # if ISC_CHECK_INVARIANT 41 /* 42 * check that this computes properly: do a roundtrip! That's the only 43 * sensible test here, but it's a rather expensive invariant... 44 */ 45 jt.yearday = 0; 46 jt.month = 1; 47 jt.monthday = 1; 48 jt.hour = 0; 49 jt.minute = 0; 50 jt.second = 0; 51 NTP_INVARIANT((ntp_u_int32_t)(caltontp(&jt) + delta) == (ntp_u_int32_t)ntp_time); 52 # endif 53 54 /* The NTP time stamps (l_fp) count seconds unsigned mod 2**32, so we 55 * have to calculate this in the proper way! 56 */ 57 return (ntp_u_int32_t)(ntp_time - delta); 58 } 59