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