1 /* 2 * caljulian - determine the Julian date from an NTP time. 3 */ 4 #include <sys/types.h> 5 6 #include "ntp_types.h" 7 #include "ntp_calendar.h" 8 #include "ntp_stdlib.h" 9 #include "ntp_fp.h" 10 11 #if 0 12 /* 13 * calmonthtab - days-in-the-month table 14 */ 15 static u_short calmonthtab[11] = { 16 JAN, 17 FEB, 18 MAR, 19 APR, 20 MAY, 21 JUN, 22 JUL, 23 AUG, 24 SEP, 25 OCT, 26 NOV 27 }; 28 29 void 30 caljulian( 31 u_long ntptime, 32 register struct calendar *jt 33 ) 34 { 35 u_long ntp_day; 36 u_long minutes; 37 /* 38 * Absolute, zero-adjusted Christian era day, starting from the 39 * mythical day 12/1/1 BC 40 */ 41 u_long acez_day; 42 43 u_long d400; /* Days into a Gregorian cycle */ 44 u_long d100; /* Days into a normal century */ 45 u_long d4; /* Days into a 4-year cycle */ 46 u_long n400; /* # of Gregorian cycles */ 47 u_long n100; /* # of normal centuries */ 48 u_long n4; /* # of 4-year cycles */ 49 u_long n1; /* # of years into a leap year */ 50 /* cycle */ 51 52 /* 53 * Do the easy stuff first: take care of hh:mm:ss, ignoring leap 54 * seconds 55 */ 56 jt->second = (u_char)(ntptime % SECSPERMIN); 57 minutes = ntptime / SECSPERMIN; 58 jt->minute = (u_char)(minutes % MINSPERHR); 59 jt->hour = (u_char)((minutes / MINSPERHR) % HRSPERDAY); 60 61 /* 62 * Find the day past 1900/01/01 00:00 UTC 63 */ 64 ntp_day = ntptime / SECSPERDAY; 65 acez_day = DAY_NTP_STARTS + ntp_day - 1; 66 n400 = acez_day/GREGORIAN_CYCLE_DAYS; 67 d400 = acez_day%GREGORIAN_CYCLE_DAYS; 68 n100 = d400 / GREGORIAN_NORMAL_CENTURY_DAYS; 69 d100 = d400 % GREGORIAN_NORMAL_CENTURY_DAYS; 70 n4 = d100 / GREGORIAN_NORMAL_LEAP_CYCLE_DAYS; 71 d4 = d100 % GREGORIAN_NORMAL_LEAP_CYCLE_DAYS; 72 n1 = d4 / DAYSPERYEAR; 73 74 /* 75 * Calculate the year and year-of-day 76 */ 77 jt->yearday = (u_short)(1 + d4%DAYSPERYEAR); 78 jt->year = (u_short)(400*n400 + 100*n100 + n4*4 + n1); 79 80 if (n100 == 4 || n1 == 4) 81 { 82 /* 83 * If the cycle year ever comes out to 4, it must be December 31st 84 * of a leap year. 85 */ 86 jt->month = 12; 87 jt->monthday = 31; 88 jt->yearday = 366; 89 } 90 else 91 { 92 /* 93 * Else, search forwards through the months to get the right month 94 * and date. 95 */ 96 int monthday; 97 98 jt->year++; 99 monthday = jt->yearday; 100 101 for (jt->month=0;jt->month<11; jt->month++) 102 { 103 int t; 104 105 t = monthday - calmonthtab[jt->month]; 106 if (jt->month == 1 && is_leapyear(jt->year)) 107 t--; 108 109 if (t > 0) 110 monthday = t; 111 else 112 break; 113 } 114 jt->month++; 115 jt->monthday = (u_char) monthday; 116 } 117 } 118 #else 119 120 /* Updated 2003-12-30 TMa 121 122 Uses common code with the *prettydate functions to convert an ntp 123 seconds count into a calendar date. 124 Will handle ntp epoch wraparound as long as the underlying os/library 125 does so for the unix epoch, i.e. works after 2038. 126 */ 127 128 void 129 caljulian( 130 u_long ntptime, 131 register struct calendar *jt 132 ) 133 { 134 struct tm *tm; 135 136 tm = ntp2unix_tm(ntptime, 0); 137 138 jt->hour = (u_char) tm->tm_hour; 139 jt->minute = (u_char) tm->tm_min; 140 jt->month = (u_char) (tm->tm_mon + 1); 141 jt->monthday = (u_char) tm->tm_mday; 142 jt->second = (u_char) tm->tm_sec; 143 jt->year = (u_short) (tm->tm_year + 1900); 144 jt->yearday = (u_short) (tm->tm_yday + 1); /* Assumes tm_yday starts with day 0! */ 145 } 146 #endif 147