1/* $NetBSD$ */ 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 */ 20u_long 21calyearstart(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