1 /* 2 * ntp_calendar.h - definitions for the calendar time-of-day routine 3 */ 4 #ifndef GUARD_NTP_CALENDAR_H 5 #define GUARD_NTP_CALENDAR_H 6 7 #include <time.h> 8 9 #include "ntp_types.h" 10 11 /* gregorian calendar date */ 12 struct calendar { 13 uint16_t year; /* year (A.D.) */ 14 uint16_t yearday; /* day of year, 1 = January 1 */ 15 uint8_t month; /* month, 1 = January */ 16 uint8_t monthday; /* day of month */ 17 uint8_t hour; /* hour of day, midnight = 0 */ 18 uint8_t minute; /* minute of hour */ 19 uint8_t second; /* second of minute */ 20 uint8_t weekday; /* 0..7, 0=Sunday */ 21 }; 22 23 /* general split representation */ 24 typedef struct { 25 int32_t hi; 26 int32_t lo; 27 } ntpcal_split; 28 29 typedef time_t (*systime_func_ptr)(time_t *); 30 31 /* 32 * We deal in a 4 year cycle starting at March 1, 1900. We assume 33 * we will only want to deal with dates since then, and not to exceed 34 * the rollover day in 2036. 35 */ 36 #define SECSPERMIN (60) /* seconds per minute */ 37 #define MINSPERHR (60) /* minutes per hour */ 38 #define HRSPERDAY (24) /* hours per day */ 39 #define DAYSPERWEEK (7) /* days per week */ 40 #define DAYSPERYEAR (365) /* days per year */ 41 42 #define SECSPERHR (SECSPERMIN * MINSPERHR) 43 #define SECSPERDAY (SECSPERHR * HRSPERDAY) 44 #define SECSPERWEEK (DAYSPERWEEK * SECSPERDAY) 45 #define SECSPERYEAR (365 * SECSPERDAY) /* regular year */ 46 #define SECSPERLEAPYEAR (366 * SECSPERDAY) /* leap year */ 47 #define SECSPERAVGYEAR 31556952 /* mean year length over 400yrs */ 48 49 /* 50 * Get the build date & time in UTC. This depends on the BUILD_EPOCH 51 * which is fixed at configure time. 52 */ 53 extern bool 54 ntpcal_get_build_date(struct calendar * /* jd */); 55 56 /* 57 * Convert a timestamp in NTP scale to a time_t value in the UN*X 58 * scale with proper epoch unfolding around a given pivot or the 59 * current system time. 60 */ 61 extern time64_t 62 ntpcal_ntp_to_time(uint32_t /* ntp */, time_t /* pivot */); 63 64 /* 65 * Convert a timestamp in NTP scale to a 64bit seconds value in the NTP 66 * scale with proper epoch unfolding around a given pivot or the current 67 * system time. 68 * Note: The pivot must be given in UN*X time scale! 69 */ 70 extern time64_t 71 ntpcal_ntp_to_ntp(uint32_t /* ntp */, time_t /* pivot */); 72 73 /* 74 * Split a time stamp in seconds into elapsed days and elapsed seconds 75 * since midnight. 76 */ 77 extern ntpcal_split 78 ntpcal_daysplit(const time64_t); 79 80 /* 81 * Merge a number of days and a number of seconds into seconds, 82 * expressed in 64 bits to avoid overflow. 83 */ 84 extern time64_t 85 ntpcal_dayjoin(int32_t /* days */, int32_t /* seconds */) __attribute__((const)); 86 87 /* 88 * Convert elapsed years in Era into elapsed days in Era. 89 */ 90 extern int32_t 91 ntpcal_days_in_years(int32_t /* years */) __attribute__((const)); 92 93 #define days_per_year(x) ((x) % 4 ? 365 : ((x % 400) ? ((x % 100) ? 366 : 365) : 366)) 94 95 /* 96 * Convert ELAPSED years/months/days of gregorian calendar to elapsed 97 * days in Gregorian epoch. No range checks done here! 98 */ 99 extern int32_t 100 ntpcal_edate_to_eradays(int32_t /* years */, int32_t /* months */, int32_t /* mdays */); 101 102 /* 103 * Convert a time spec to seconds. No range checks done here! 104 */ 105 extern int32_t 106 ntpcal_etime_to_seconds(int32_t /* hours */, int32_t /* minutes */, 107 int32_t /* seconds */) __attribute__((const)); 108 109 /* 110 * Convert the date part of a 'struct tm' (that is, year, month, 111 * day-of-month) into the RataDie of that day. 112 */ 113 extern int32_t 114 ntpcal_tm_to_rd(const struct tm * /* utm */); 115 116 /* 117 * Convert the date part of a 'struct calendar' (that is, year, month, 118 * day-of-month) into the RataDie of that day. 119 */ 120 extern int32_t 121 ntpcal_date_to_rd(const struct calendar * /* jt */); 122 123 /* 124 * Given the number of elapsed days in the calendar era, split this 125 * number into the number of elapsed years in 'res.quot' and the 126 * number of elapsed days of that year in 'res.rem'. 127 * 128 * if 'isleapyear' is not NULL, it will receive an integer that is 0 129 * for regular years and a non-zero value for leap years. 130 */ 131 extern ntpcal_split 132 ntpcal_split_eradays(int32_t /* days */, int32_t * /* isleapyear */); 133 134 /* 135 * Given a number of elapsed days in a year and a leap year indicator, 136 * split the number of elapsed days into the number of elapsed months 137 * in 'res.quot' and the number of elapsed days of that month in 138 * 'res.rem'. 139 */ 140 extern ntpcal_split 141 ntpcal_split_yeardays(int32_t /* eyd */, bool /* isleapyear */); 142 143 /* 144 * Convert a RataDie number into the date part of a 'struct 145 * calendar'. Return 0 if the year is regular year, 1 if the year is 146 * a leap year, -1 if the calculation overflowed. 147 */ 148 extern int 149 ntpcal_rd_to_date(struct calendar * /* jt */, int32_t /* rd */); 150 151 /* 152 * Take a value of seconds since midnight and split it into hhmmss in 153 * a 'struct calendar'. Return excessive days. 154 */ 155 /* used by ntpd/refclock_nmea.c */ 156 extern int32_t 157 ntpcal_daysec_to_date(struct calendar * /* jt */, int32_t /* secs */); 158 159 /* 160 * Take the time part of a 'struct calendar' and return the seconds 161 * since midnight. 162 */ 163 /* used by ntpd/refclock_nmea.c */ 164 extern int32_t 165 ntpcal_date_to_daysec(const struct calendar *); 166 167 extern int32_t 168 ntpcal_tm_to_daysec(const struct tm * /* utm */); 169 170 extern int 171 ntpcal_time_to_date(struct calendar * /* jd */, const time64_t /* ts */); 172 173 extern int32_t 174 ntpcal_periodic_extend(int32_t /* pivot */, int32_t /* value */, 175 int32_t /* cycle */) __attribute__((const)); 176 177 extern int 178 ntpcal_ntp64_to_date(struct calendar * /* jd */, const time64_t /* ntp */); 179 180 extern int 181 ntpcal_ntp_to_date(struct calendar * /* jd */, uint32_t /* ntp */, 182 time_t /* pivot */); 183 184 extern time_t 185 ntpcal_date_to_time(const struct calendar * /* jd */); 186 187 188 /* 189 * Additional support stuff for Ed Rheingold's calendrical calculations 190 */ 191 192 /* 193 * Start day of NTP time as days past the imaginary date 12/1/1 BC. 194 * (This is the beginning of the Christian Era, or BCE.) 195 */ 196 #define DAY_NTP_STARTS 693596 197 198 /* 199 * Start day of the UNIX epoch. This is the Rata Die of 1970-01-01. 200 */ 201 #define DAY_UNIX_STARTS 719163 202 203 /* 204 * Difference between UN*X and NTP epoch (25567). 205 */ 206 #define NTP_TO_UNIX_DAYS (DAY_UNIX_STARTS - DAY_NTP_STARTS) 207 208 /* 209 * Days in a normal 4 year leap year calendar cycle (1461). 210 */ 211 #define GREGORIAN_NORMAL_LEAP_CYCLE_DAYS (3 * 365 + 366) 212 213 /* 214 * Days in a normal 100 year leap year calendar (36524). We lose a 215 * leap day in years evenly divisible by 100 but not by 400. 216 */ 217 #define GREGORIAN_NORMAL_CENTURY_DAYS \ 218 (25 * GREGORIAN_NORMAL_LEAP_CYCLE_DAYS - 1) 219 220 /* 221 * The Gregorian calendar is based on a 400 year cycle. This is the 222 * number of days in each cycle (146097). We gain a leap day in years 223 * divisible by 400 relative to the "normal" century. 224 */ 225 #define GREGORIAN_CYCLE_DAYS (4 * GREGORIAN_NORMAL_CENTURY_DAYS + 1) 226 227 /* 228 * Number of weeks in 400 years (20871). 229 */ 230 #define GREGORIAN_CYCLE_WEEKS (GREGORIAN_CYCLE_DAYS / 7) 231 232 #define is_leapyear(y) (!((y) % 4) && !(!((y) % 100) && (y) % 400)) 233 234 /* 235 * Time of day conversion constant. NTP's time scale starts in 1900, 236 * Unix in 1970. The value is 1970 - 1900 in seconds, 0x83aa7e80 or 237 * 2208988800. This is larger than 32-bit INT_MAX, so unsigned 238 * type is forced. 239 */ 240 #define JAN_1970 ((unsigned int)NTP_TO_UNIX_DAYS * (unsigned int)SECSPERDAY) 241 242 #endif 243