1c0b746e5SOllivier Robert /* 2c0b746e5SOllivier Robert * caljulian - determine the Julian date from an NTP time. 3c0b746e5SOllivier Robert */ 4c0b746e5SOllivier Robert #include <sys/types.h> 5c0b746e5SOllivier Robert 6c0b746e5SOllivier Robert #include "ntp_types.h" 7c0b746e5SOllivier Robert #include "ntp_calendar.h" 8c0b746e5SOllivier Robert #include "ntp_stdlib.h" 9c0b746e5SOllivier Robert 10c0b746e5SOllivier Robert /* 11c0b746e5SOllivier Robert * calmonthtab - days-in-the-month table 12c0b746e5SOllivier Robert */ 13c0b746e5SOllivier Robert static u_short calmonthtab[11] = { 14c0b746e5SOllivier Robert JAN, 15c0b746e5SOllivier Robert FEB, 16c0b746e5SOllivier Robert MAR, 17c0b746e5SOllivier Robert APR, 18c0b746e5SOllivier Robert MAY, 19c0b746e5SOllivier Robert JUN, 20c0b746e5SOllivier Robert JUL, 21c0b746e5SOllivier Robert AUG, 22c0b746e5SOllivier Robert SEP, 23c0b746e5SOllivier Robert OCT, 24c0b746e5SOllivier Robert NOV 25c0b746e5SOllivier Robert }; 26c0b746e5SOllivier Robert 27c0b746e5SOllivier Robert void 28c0b746e5SOllivier Robert caljulian( 29c0b746e5SOllivier Robert u_long ntptime, 30c0b746e5SOllivier Robert register struct calendar *jt 31c0b746e5SOllivier Robert ) 32c0b746e5SOllivier Robert { 33c0b746e5SOllivier Robert u_long ntp_day; 34c0b746e5SOllivier Robert u_long minutes; 35c0b746e5SOllivier Robert /* 36c0b746e5SOllivier Robert * Absolute, zero-adjusted Christian era day, starting from the 37c0b746e5SOllivier Robert * mythical day 12/1/1 BC 38c0b746e5SOllivier Robert */ 39c0b746e5SOllivier Robert u_long acez_day; 40c0b746e5SOllivier Robert 41c0b746e5SOllivier Robert u_long d400; /* Days into a Gregorian cycle */ 42c0b746e5SOllivier Robert u_long d100; /* Days into a normal century */ 43c0b746e5SOllivier Robert u_long d4; /* Days into a 4-year cycle */ 44c0b746e5SOllivier Robert u_long n400; /* # of Gregorian cycles */ 45c0b746e5SOllivier Robert u_long n100; /* # of normal centuries */ 46c0b746e5SOllivier Robert u_long n4; /* # of 4-year cycles */ 47c0b746e5SOllivier Robert u_long n1; /* # of years into a leap year */ 48c0b746e5SOllivier Robert /* cycle */ 49c0b746e5SOllivier Robert 50c0b746e5SOllivier Robert /* 51c0b746e5SOllivier Robert * Do the easy stuff first: take care of hh:mm:ss, ignoring leap 52c0b746e5SOllivier Robert * seconds 53c0b746e5SOllivier Robert */ 54c0b746e5SOllivier Robert jt->second = (u_char)(ntptime % SECSPERMIN); 55c0b746e5SOllivier Robert minutes = ntptime / SECSPERMIN; 56c0b746e5SOllivier Robert jt->minute = (u_char)(minutes % MINSPERHR); 57c0b746e5SOllivier Robert jt->hour = (u_char)((minutes / MINSPERHR) % HRSPERDAY); 58c0b746e5SOllivier Robert 59c0b746e5SOllivier Robert /* 60c0b746e5SOllivier Robert * Find the day past 1900/01/01 00:00 UTC 61c0b746e5SOllivier Robert */ 62c0b746e5SOllivier Robert ntp_day = ntptime / SECSPERDAY; 63c0b746e5SOllivier Robert acez_day = DAY_NTP_STARTS + ntp_day - 1; 64c0b746e5SOllivier Robert n400 = acez_day/GREGORIAN_CYCLE_DAYS; 65c0b746e5SOllivier Robert d400 = acez_day%GREGORIAN_CYCLE_DAYS; 66c0b746e5SOllivier Robert n100 = d400 / GREGORIAN_NORMAL_CENTURY_DAYS; 67c0b746e5SOllivier Robert d100 = d400 % GREGORIAN_NORMAL_CENTURY_DAYS; 68c0b746e5SOllivier Robert n4 = d100 / GREGORIAN_NORMAL_LEAP_CYCLE_DAYS; 69c0b746e5SOllivier Robert d4 = d100 % GREGORIAN_NORMAL_LEAP_CYCLE_DAYS; 70c0b746e5SOllivier Robert n1 = d4 / DAYSPERYEAR; 71c0b746e5SOllivier Robert 72c0b746e5SOllivier Robert /* 73c0b746e5SOllivier Robert * Calculate the year and year-of-day 74c0b746e5SOllivier Robert */ 75c0b746e5SOllivier Robert jt->yearday = (u_short)(1 + d4%DAYSPERYEAR); 76c0b746e5SOllivier Robert jt->year = (u_short)(400*n400 + 100*n100 + n4*4 + n1); 77c0b746e5SOllivier Robert 78c0b746e5SOllivier Robert if (n100 == 4 || n1 == 4) 79c0b746e5SOllivier Robert { 80c0b746e5SOllivier Robert /* 81c0b746e5SOllivier Robert * If the cycle year ever comes out to 4, it must be December 31st 82c0b746e5SOllivier Robert * of a leap year. 83c0b746e5SOllivier Robert */ 84c0b746e5SOllivier Robert jt->month = 12; 85c0b746e5SOllivier Robert jt->monthday = 31; 86c0b746e5SOllivier Robert jt->yearday = 366; 87c0b746e5SOllivier Robert } 88c0b746e5SOllivier Robert else 89c0b746e5SOllivier Robert { 90c0b746e5SOllivier Robert /* 91c0b746e5SOllivier Robert * Else, search forwards through the months to get the right month 92c0b746e5SOllivier Robert * and date. 93c0b746e5SOllivier Robert */ 94c0b746e5SOllivier Robert int monthday; 95c0b746e5SOllivier Robert 96c0b746e5SOllivier Robert jt->year++; 97c0b746e5SOllivier Robert monthday = jt->yearday; 98c0b746e5SOllivier Robert 99c0b746e5SOllivier Robert for (jt->month=0;jt->month<11; jt->month++) 100c0b746e5SOllivier Robert { 101c0b746e5SOllivier Robert int t; 102c0b746e5SOllivier Robert 103c0b746e5SOllivier Robert t = monthday - calmonthtab[jt->month]; 104c0b746e5SOllivier Robert if (jt->month == 1 && is_leapyear(jt->year)) 105c0b746e5SOllivier Robert t--; 106c0b746e5SOllivier Robert 107c0b746e5SOllivier Robert if (t > 0) 108c0b746e5SOllivier Robert monthday = t; 109c0b746e5SOllivier Robert else 110c0b746e5SOllivier Robert break; 111c0b746e5SOllivier Robert } 112c0b746e5SOllivier Robert jt->month++; 113c0b746e5SOllivier Robert jt->monthday = monthday; 114c0b746e5SOllivier Robert } 115c0b746e5SOllivier Robert } 116