1 /* 2 * caltontp - convert a date to an NTP time 3 */ 4 #include <config.h> 5 #include <sys/types.h> 6 7 #include "ntp_types.h" 8 #include "ntp_calendar.h" 9 #include "ntp_stdlib.h" 10 #include "ntp_assert.h" 11 #include "ntp_unixtime.h" 12 13 /* 14 * Juergen Perlinger, 2008-11-12 15 * Add support for full calendar calculations. If the day-of-year is provided 16 * (that is, not zero) it will be used instead of month and day-of-month; 17 * otherwise a full turn through the calendar calculations will be taken. 18 * 19 * I know that Harlan Stenn likes to see assertions in production code, and I 20 * agree in general. But here we set 'errno' and try to do our best instead. 21 * Also note that the bounds check is a bit sloppy: It permits off-by-one 22 * on the input quantities. That permits some simple/naive adjustments to 23 * be made before calling this function. 24 * 25 * Apart from that the calendar is perfectly capable of dealing with 26 * off-scale input values! 27 * 28 * BTW: A total roundtrip using 'caljulian' would be a quite shaky thing: 29 * Because of the truncation of the NTP time stamp to 32 bits and the epoch 30 * unfolding around the current time done by 'caljulian' the roundtrip does 31 * *not* necessarily reproduce the input, especially if the time spec is more 32 * than 68 years off from the current time... 33 */ 34 35 uint32_t 36 caltontp( 37 const struct calendar *jt 38 ) 39 { 40 int32_t eraday; /* CE Rata Die number */ 41 vint64 ntptime;/* resulting NTP time */ 42 43 if (NULL == jt) { 44 errno = EINVAL; 45 return 0; 46 } 47 48 if ( (jt->month > 13) /* permit month 0..13! */ 49 || (jt->monthday > 32) 50 || (jt->yearday > 366) 51 || (jt->hour > 24) 52 || (jt->minute > MINSPERHR) 53 || (jt->second > SECSPERMIN)) 54 errno = ERANGE; 55 56 /* 57 * First convert the date to he corresponding RataDie 58 * number. If yearday is not zero, assume that it contains a 59 * useable value and avoid all calculations involving month 60 * and day-of-month. Do a full evaluation otherwise. 61 */ 62 if (jt->yearday) 63 eraday = ntpcal_year_to_ystart(jt->year) 64 + jt->yearday - 1; 65 else 66 eraday = ntpcal_date_to_rd(jt); 67 68 ntptime = ntpcal_dayjoin(eraday - DAY_NTP_STARTS, 69 ntpcal_etime_to_seconds(jt->hour, jt->minute, 70 jt->second)); 71 return ntptime.d_s.lo; 72 } 73