1c0b746e5SOllivier Robert /* 2c0b746e5SOllivier Robert * caltontp - convert a date to an NTP time 3c0b746e5SOllivier Robert */ 42b15cb3dSCy Schubert #include <config.h> 5c0b746e5SOllivier Robert #include <sys/types.h> 6c0b746e5SOllivier Robert 7c0b746e5SOllivier Robert #include "ntp_types.h" 8c0b746e5SOllivier Robert #include "ntp_calendar.h" 9c0b746e5SOllivier Robert #include "ntp_stdlib.h" 102b15cb3dSCy Schubert #include "ntp_assert.h" 112b15cb3dSCy Schubert #include "ntp_unixtime.h" 12c0b746e5SOllivier Robert 132b15cb3dSCy Schubert /* 142b15cb3dSCy Schubert * Juergen Perlinger, 2008-11-12 15*a466cc55SCy Schubert * Add support for full calendar calculations. If the day-of-year is provided 162b15cb3dSCy Schubert * (that is, not zero) it will be used instead of month and day-of-month; 172b15cb3dSCy Schubert * otherwise a full turn through the calendar calculations will be taken. 182b15cb3dSCy Schubert * 192b15cb3dSCy Schubert * I know that Harlan Stenn likes to see assertions in production code, and I 20*a466cc55SCy Schubert * agree in general. But here we set 'errno' and try to do our best instead. 21*a466cc55SCy Schubert * Also note that the bounds check is a bit sloppy: It permits off-by-one 22*a466cc55SCy Schubert * on the input quantities. That permits some simple/naive adjustments to 23*a466cc55SCy Schubert * be made before calling this function. 24*a466cc55SCy Schubert * 25*a466cc55SCy Schubert * Apart from that the calendar is perfectly capable of dealing with 26*a466cc55SCy Schubert * off-scale input values! 272b15cb3dSCy Schubert * 282b15cb3dSCy Schubert * BTW: A total roundtrip using 'caljulian' would be a quite shaky thing: 292b15cb3dSCy Schubert * Because of the truncation of the NTP time stamp to 32 bits and the epoch 302b15cb3dSCy Schubert * unfolding around the current time done by 'caljulian' the roundtrip does 312b15cb3dSCy Schubert * *not* necessarily reproduce the input, especially if the time spec is more 322b15cb3dSCy Schubert * than 68 years off from the current time... 332b15cb3dSCy Schubert */ 342b15cb3dSCy Schubert 352b15cb3dSCy Schubert uint32_t caltontp(const struct calendar * jt)36c0b746e5SOllivier Robertcaltontp( 372b15cb3dSCy Schubert const struct calendar *jt 38c0b746e5SOllivier Robert ) 39c0b746e5SOllivier Robert { 402b15cb3dSCy Schubert int32_t eraday; /* CE Rata Die number */ 412b15cb3dSCy Schubert vint64 ntptime;/* resulting NTP time */ 422b15cb3dSCy Schubert 43*a466cc55SCy Schubert if (NULL == jt) { 44*a466cc55SCy Schubert errno = EINVAL; 45*a466cc55SCy Schubert return 0; 46*a466cc55SCy Schubert } 472b15cb3dSCy Schubert 48*a466cc55SCy Schubert if ( (jt->month > 13) /* permit month 0..13! */ 49*a466cc55SCy Schubert || (jt->monthday > 32) 50*a466cc55SCy Schubert || (jt->yearday > 366) 51*a466cc55SCy Schubert || (jt->hour > 24) 52*a466cc55SCy Schubert || (jt->minute > MINSPERHR) 53*a466cc55SCy Schubert || (jt->second > SECSPERMIN)) 54*a466cc55SCy Schubert errno = ERANGE; 55c0b746e5SOllivier Robert 56c0b746e5SOllivier Robert /* 572b15cb3dSCy Schubert * First convert the date to he corresponding RataDie 582b15cb3dSCy Schubert * number. If yearday is not zero, assume that it contains a 592b15cb3dSCy Schubert * useable value and avoid all calculations involving month 602b15cb3dSCy Schubert * and day-of-month. Do a full evaluation otherwise. 61c0b746e5SOllivier Robert */ 622b15cb3dSCy Schubert if (jt->yearday) 632b15cb3dSCy Schubert eraday = ntpcal_year_to_ystart(jt->year) 642b15cb3dSCy Schubert + jt->yearday - 1; 652b15cb3dSCy Schubert else 662b15cb3dSCy Schubert eraday = ntpcal_date_to_rd(jt); 67c0b746e5SOllivier Robert 682b15cb3dSCy Schubert ntptime = ntpcal_dayjoin(eraday - DAY_NTP_STARTS, 692b15cb3dSCy Schubert ntpcal_etime_to_seconds(jt->hour, jt->minute, 702b15cb3dSCy Schubert jt->second)); 712b15cb3dSCy Schubert return ntptime.d_s.lo; 72c0b746e5SOllivier Robert } 73