2 * ntp_calendar.h - definitions for the calendar time-of-day routine
11 /* gregorian calendar date */
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 */
23 /* ISO week calendar date */
25 uint16_t year; /* year (A.D.) */
26 uint8_t week; /* 1..53, week in year */
27 uint8_t weekday; /* 1..7, 1=Monday */
28 uint8_t hour; /* hour of day, midnight = 0 */
29 uint8_t minute; /* minute of hour */
30 uint8_t second; /* second of minute */
33 /* general split representation */
39 typedef time_t (*systime_func_ptr)(time_t *);
42 * set the function for getting the system time. This is mostly used for
43 * unit testing to provide a fixed / shifted time stamp. Setting the
44 * value to NULL restores the original function, that is, 'time()',
45 * which is also the automatic default.
47 extern systime_func_ptr ntpcal_set_timefunc(systime_func_ptr);
55 #define CAL_WEDNESDAY 3
56 #define CAL_THURSDAY 4
58 #define CAL_SATURDAY 6
59 #define CAL_SUNDAY7 7 /* also sunday */
62 * Days in each month. 30 days hath September...
79 * We deal in a 4 year cycle starting at March 1, 1900. We assume
80 * we will only want to deal with dates since then, and not to exceed
81 * the rollover day in 2036.
83 #define SECSPERMIN (60) /* seconds per minute */
84 #define MINSPERHR (60) /* minutes per hour */
85 #define HRSPERDAY (24) /* hours per day */
86 #define DAYSPERWEEK (7) /* days per week */
87 #define DAYSPERYEAR (365) /* days per year */
89 #define SECSPERHR (SECSPERMIN * MINSPERHR)
90 #define SECSPERDAY (SECSPERHR * HRSPERDAY)
91 #define SECSPERWEEK (DAYSPERWEEK * SECSPERDAY)
92 #define SECSPERYEAR (365 * SECSPERDAY) /* regular year */
93 #define SECSPERLEAPYEAR (366 * SECSPERDAY) /* leap year */
94 #define SECSPERAVGYEAR 31556952 /* mean year length over 400yrs */
96 #define GPSWEEKS 1024 /* GPS week cycle */
98 * Gross hacks. I have illicit knowlege that there won't be overflows
99 * here, the compiler often can't tell this.
101 #define TIMES60(val) ((((val)<<4) - (val))<<2) /* *(16 - 1) * 4 */
102 #define TIMES24(val) (((val)<<4) + ((val)<<3)) /* *16 + *8 */
103 #define TIMES7(val) (((val)<<3) - (val)) /* *8 - *1 */
104 #define TIMESDPERC(val) (((val)<<10) + ((val)<<8) \
105 + ((val)<<7) + ((val)<<5) \
106 + ((val)<<4) + ((val)<<2) + (val)) /* *big* hack */
109 extern const char * const months[12];
110 extern const char * const daynames[7];
112 extern void caljulian (uint32_t, struct calendar *);
113 extern uint32_t caltontp (const struct calendar *);
116 * Convert between 'time_t' and 'vint64'
118 extern vint64 time_to_vint64(const time_t *);
119 extern time_t vint64_to_time(const vint64 *);
122 * Get the build date & time. ATTENTION: The time zone is not specified!
123 * This depends entirely on the C compilers' capabilities to properly
124 * expand the '__TIME__' and '__DATE__' macros, as required by the C
128 ntpcal_get_build_date(struct calendar * /* jd */);
131 * Convert a timestamp in NTP scale to a time_t value in the UN*X
132 * scale with proper epoch unfolding around a given pivot or the
133 * current system time.
136 ntpcal_ntp_to_time(uint32_t /* ntp */, const time_t * /* pivot */);
139 * Convert a timestamp in NTP scale to a 64bit seconds value in the NTP
140 * scale with proper epoch unfolding around a given pivot or the current
142 * Note: The pivot must be given in UN*X time scale!
145 ntpcal_ntp_to_ntp(uint32_t /* ntp */, const time_t * /* pivot */);
148 * Split a time stamp in seconds into elapsed days and elapsed seconds
152 ntpcal_daysplit(const vint64 *);
155 * Merge a number of days and a number of seconds into seconds,
156 * expressed in 64 bits to avoid overflow.
159 ntpcal_dayjoin(int32_t /* days */, int32_t /* seconds */);
161 /* Get the number of leap years since epoch for the number of elapsed
165 ntpcal_leapyears_in_years(int32_t /* years */);
168 * Convert elapsed years in Era into elapsed days in Era.
171 ntpcal_days_in_years(int32_t /* years */);
174 * Convert a number of elapsed month in a year into elapsed days
177 * The month will be normalized, and 'res.hi' will contain the
178 * excessive years that must be considered when converting the years,
179 * while 'res.lo' will contain the days since start of the
180 * year. (Expect the resulting days to be negative, with a positive
181 * excess! But then, we need no leap year flag, either...)
184 ntpcal_days_in_months(int32_t /* months */);
187 * Convert ELAPSED years/months/days of gregorian calendar to elapsed
188 * days in Gregorian epoch. No range checks done here!
191 ntpcal_edate_to_eradays(int32_t /* years */, int32_t /* months */, int32_t /* mdays */);
194 * Convert a time spec to seconds. No range checks done here!
197 ntpcal_etime_to_seconds(int32_t /* hours */, int32_t /* minutes */, int32_t /* seconds */);
200 * Convert ELAPSED years/months/days of gregorian calendar to elapsed
203 * Note: This will give the true difference to the start of the given year,
204 * even if months & days are off-scale.
207 ntpcal_edate_to_yeardays(int32_t /* years */, int32_t /* months */, int32_t /* mdays */);
210 * Convert the date part of a 'struct tm' (that is, year, month,
211 * day-of-month) into the RataDie of that day.
214 ntpcal_tm_to_rd(const struct tm * /* utm */);
217 * Convert the date part of a 'struct calendar' (that is, year, month,
218 * day-of-month) into the RataDie of that day.
221 ntpcal_date_to_rd(const struct calendar * /* jt */);
224 * Given the number of elapsed days in the calendar era, split this
225 * number into the number of elapsed years in 'res.quot' and the
226 * number of elapsed days of that year in 'res.rem'.
228 * if 'isleapyear' is not NULL, it will receive an integer that is 0
229 * for regular years and a non-zero value for leap years.
231 * The input is limited to [-2^30, 2^30-1]. If the days exceed this
232 * range, errno is set to EDOM and the result is saturated.
235 ntpcal_split_eradays(int32_t /* days */, int/*BOOL*/ * /* isleapyear */);
238 * Given a number of elapsed days in a year and a leap year indicator,
239 * split the number of elapsed days into the number of elapsed months
240 * in 'res.quot' and the number of elapsed days of that month in
244 ntpcal_split_yeardays(int32_t /* eyd */, int/*BOOL*/ /* isleapyear */);
247 * Convert a RataDie number into the date part of a 'struct
248 * calendar'. Return 0 if the year is regular year, !0 if the year is
252 ntpcal_rd_to_date(struct calendar * /* jt */, int32_t /* rd */);
255 * Convert a RataDie number into the date part of a 'struct
256 * tm'. Return 0 if the year is regular year, !0 if the year is a leap
260 ntpcal_rd_to_tm(struct tm * /* utm */, int32_t /* rd */);
263 * Take a value of seconds since midnight and split it into hhmmss in
264 * a 'struct calendar'. Return excessive days.
267 ntpcal_daysec_to_date(struct calendar * /* jt */, int32_t /* secs */);
270 * Take the time part of a 'struct calendar' and return the seconds
274 ntpcal_date_to_daysec(const struct calendar *);
277 * Take a value of seconds since midnight and split it into hhmmss in
278 * a 'struct tm'. Return excessive days.
281 ntpcal_daysec_to_tm(struct tm * /* utm */, int32_t /* secs */);
284 ntpcal_tm_to_daysec(const struct tm * /* utm */);
287 * convert a year number to rata die of year start
290 ntpcal_year_to_ystart(int32_t /* year */);
293 * For a given RataDie, get the RataDie of the associated year start,
294 * that is, the RataDie of the last January,1st on or before that day.
297 ntpcal_rd_to_ystart(int32_t /* rd */);
300 * convert a RataDie to the RataDie of start of the calendar month.
303 ntpcal_rd_to_mstart(int32_t /* year */);
307 ntpcal_daysplit_to_date(struct calendar * /* jt */,
308 const ntpcal_split * /* ds */, int32_t /* dof */);
311 ntpcal_daysplit_to_tm(struct tm * /* utm */, const ntpcal_split * /* ds */,
315 ntpcal_time_to_date(struct calendar * /* jd */, const vint64 * /* ts */);
318 ntpcal_periodic_extend(int32_t /* pivot */, int32_t /* value */,
319 int32_t /* cycle */);
322 ntpcal_ntp64_to_date(struct calendar * /* jd */, const vint64 * /* ntp */);
325 ntpcal_ntp_to_date(struct calendar * /* jd */, uint32_t /* ntp */,
326 const time_t * /* pivot */);
329 ntpcal_date_to_ntp64(const struct calendar * /* jd */);
332 ntpcal_date_to_ntp(const struct calendar * /* jd */);
335 ntpcal_date_to_time(const struct calendar * /* jd */);
338 * ISO week-calendar conversions
341 isocal_weeks_in_years(int32_t /* years */);
344 * The input is limited to [-2^30, 2^30-1]. If the weeks exceed this
345 * range, errno is set to EDOM and the result is saturated.
348 isocal_split_eraweeks(int32_t /* weeks */);
351 isocal_ntp64_to_date(struct isodate * /* id */, const vint64 * /* ntp */);
354 isocal_ntp_to_date(struct isodate * /* id */, uint32_t /* ntp */,
355 const time_t * /* pivot */);
358 isocal_date_to_ntp64(const struct isodate * /* id */);
361 isocal_date_to_ntp(const struct isodate * /* id */);
365 * day-of-week calculations
367 * Given a RataDie and a day-of-week, calculate a RDN that is reater-than,
368 * greater-or equal, closest, less-or-equal or less-than the given RDN
369 * and denotes the given day-of-week
372 ntpcal_weekday_gt(int32_t /* rdn */, int32_t /* dow */);
375 ntpcal_weekday_ge(int32_t /* rdn */, int32_t /* dow */);
378 ntpcal_weekday_close(int32_t /* rdn */, int32_t /* dow */);
381 ntpcal_weekday_le(int32_t /* rdn */, int32_t /* dow */);
384 ntpcal_weekday_lt(int32_t /* rdn */, int32_t /* dow */);
388 * handling of base date spec
391 basedate_eval_buildstamp(void);
394 basedate_eval_string(const char *str);
397 basedate_set_day(int32_t dayno);
400 basedate_get_day(void);
403 basedate_get_eracenter(void);
406 basedate_get_erabase(void);
409 basedate_get_gpsweek(void);
412 basedate_expand_gpsweek(unsigned short weekno);
415 * Additional support stuff for Ed Rheingold's calendrical calculations
419 * Start day of NTP time as days past 0000-12-31 in the proleptic
420 * Gregorian calendar. (So 0001-01-01 is day number 1; this is the Rata
421 * Die counting scheme used by Ed Rheingold in his book "Calendrical
424 #define DAY_NTP_STARTS 693596
427 * Start day of the UNIX epoch. This is the Rata Die of 1970-01-01.
429 #define DAY_UNIX_STARTS 719163
432 * Start day of the GPS epoch. This is the Rata Die of 1980-01-06
434 #define DAY_GPS_STARTS 722819
437 * Difference between UN*X and NTP epoch (25567).
439 #define NTP_TO_UNIX_DAYS (DAY_UNIX_STARTS - DAY_NTP_STARTS)
442 * Difference between GPS and NTP epoch (29224)
444 #define NTP_TO_GPS_DAYS (DAY_GPS_STARTS - DAY_NTP_STARTS)
447 * Days in a normal 4 year leap year calendar cycle (1461).
449 #define GREGORIAN_NORMAL_LEAP_CYCLE_DAYS (4 * 365 + 1)
452 * Days in a normal 100 year leap year calendar (36524). We lose a
453 * leap day in years evenly divisible by 100 but not by 400.
455 #define GREGORIAN_NORMAL_CENTURY_DAYS \
456 (25 * GREGORIAN_NORMAL_LEAP_CYCLE_DAYS - 1)
459 * The Gregorian calendar is based on a 400 year cycle. This is the
460 * number of days in each cycle (146097). We gain a leap day in years
461 * divisible by 400 relative to the "normal" century.
463 #define GREGORIAN_CYCLE_DAYS (4 * GREGORIAN_NORMAL_CENTURY_DAYS + 1)
466 * Number of weeks in 400 years (20871).
468 #define GREGORIAN_CYCLE_WEEKS (GREGORIAN_CYCLE_DAYS / 7)
470 #define is_leapyear(y) (!((y) % 4) && !(!((y) % 100) && (y) % 400))