106 lines
2.4 KiB
C
106 lines
2.4 KiB
C
|
/*
|
||
|
* caljulian - determine the Julian date from an NTP time.
|
||
|
*/
|
||
|
#include <sys/types.h>
|
||
|
|
||
|
#include "ntp_types.h"
|
||
|
#include "ntp_calendar.h"
|
||
|
#include "ntp_stdlib.h"
|
||
|
|
||
|
/*
|
||
|
* calmonthtab - month start offsets from the beginning of a cycle.
|
||
|
*/
|
||
|
static u_short calmonthtab[12] = {
|
||
|
0, /* March */
|
||
|
MAR, /* April */
|
||
|
(MAR+APR), /* May */
|
||
|
(MAR+APR+MAY), /* June */
|
||
|
(MAR+APR+MAY+JUN), /* July */
|
||
|
(MAR+APR+MAY+JUN+JUL), /* August */
|
||
|
(MAR+APR+MAY+JUN+JUL+AUG), /* September */
|
||
|
(MAR+APR+MAY+JUN+JUL+AUG+SEP), /* October */
|
||
|
(MAR+APR+MAY+JUN+JUL+AUG+SEP+OCT), /* November */
|
||
|
(MAR+APR+MAY+JUN+JUL+AUG+SEP+OCT+NOV), /* December */
|
||
|
(MAR+APR+MAY+JUN+JUL+AUG+SEP+OCT+NOV+DEC), /* January */
|
||
|
(MAR+APR+MAY+JUN+JUL+AUG+SEP+OCT+NOV+DEC+JAN), /* February */
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* caldaytab - calendar year start day offsets
|
||
|
*/
|
||
|
static u_short caldaytab[YEARSPERCYCLE] = {
|
||
|
(DAYSPERYEAR - (JAN + FEB)),
|
||
|
((DAYSPERYEAR * 2) - (JAN + FEB)),
|
||
|
((DAYSPERYEAR * 3) - (JAN + FEB)),
|
||
|
((DAYSPERYEAR * 4) - (JAN + FEB)),
|
||
|
};
|
||
|
|
||
|
void
|
||
|
caljulian(ntptime, jt)
|
||
|
u_long ntptime;
|
||
|
register struct calendar *jt;
|
||
|
{
|
||
|
register int i;
|
||
|
register u_long nt;
|
||
|
register u_short snt;
|
||
|
register int cyear;
|
||
|
|
||
|
/*
|
||
|
* Find the start of the cycle this is in.
|
||
|
*/
|
||
|
nt = ntptime;
|
||
|
if (nt >= MAR1988) {
|
||
|
cyear = CYCLE22;
|
||
|
nt -= MAR1988;
|
||
|
} else {
|
||
|
cyear = 0;
|
||
|
nt -= MAR1900;
|
||
|
}
|
||
|
while (nt >= SECSPERCYCLE) {
|
||
|
nt -= SECSPERCYCLE;
|
||
|
cyear++;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Seconds, minutes and hours are too hard to do without
|
||
|
* divides, so we don't.
|
||
|
*/
|
||
|
jt->second = (u_char) (nt % SECSPERMIN);
|
||
|
nt /= SECSPERMIN; /* nt in minutes */
|
||
|
jt->minute = (u_char) (nt % MINSPERHR);
|
||
|
snt = (u_short) (nt / MINSPERHR); /* snt in hours */
|
||
|
jt->hour = (u_char) (snt % HRSPERDAY);
|
||
|
snt /= HRSPERDAY; /* nt in days */
|
||
|
|
||
|
/*
|
||
|
* snt is now the number of days into the cycle, from 0 to 1460.
|
||
|
*/
|
||
|
cyear <<= 2;
|
||
|
if (snt < caldaytab[0]) {
|
||
|
jt->yearday = snt + JAN + FEBLEAP + 1; /* first year is leap */
|
||
|
} else {
|
||
|
for (i = 1; i < YEARSPERCYCLE; i++)
|
||
|
if (snt < caldaytab[i])
|
||
|
break;
|
||
|
jt->yearday = snt - caldaytab[i-1] + 1;
|
||
|
cyear += i;
|
||
|
}
|
||
|
jt->year = cyear + 1900;
|
||
|
|
||
|
/*
|
||
|
* One last task, to compute the month and day. Normalize snt to
|
||
|
* a day within a cycle year.
|
||
|
*/
|
||
|
while (snt >= DAYSPERYEAR)
|
||
|
snt -= DAYSPERYEAR;
|
||
|
for (i = 0; i < 11; i++)
|
||
|
if (snt < calmonthtab[i+1])
|
||
|
break;
|
||
|
|
||
|
if (i > 9)
|
||
|
jt->month = i - 9; /* January or February */
|
||
|
else
|
||
|
jt->month = i + 3; /* March through December */
|
||
|
jt->monthday = snt - calmonthtab[i] + 1;
|
||
|
}
|