aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/xntpd/lib/caljulian.c
blob: 070fa0d6f34ef650816e5040ed4a10eb51cfb378 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
 * 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 = nt % SECSPERMIN;
	nt /= SECSPERMIN;		/* nt in minutes */
	jt->minute = nt % MINSPERHR;
	snt = nt / MINSPERHR;		/* snt in hours */
	jt->hour = 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;
}