aboutsummaryrefslogtreecommitdiff
path: root/contrib/ntp/libntp/caljulian.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ntp/libntp/caljulian.c')
-rw-r--r--contrib/ntp/libntp/caljulian.c115
1 files changed, 115 insertions, 0 deletions
diff --git a/contrib/ntp/libntp/caljulian.c b/contrib/ntp/libntp/caljulian.c
new file mode 100644
index 000000000000..948bb1c57dd8
--- /dev/null
+++ b/contrib/ntp/libntp/caljulian.c
@@ -0,0 +1,115 @@
+/*
+ * 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 - days-in-the-month table
+ */
+static u_short calmonthtab[11] = {
+ JAN,
+ FEB,
+ MAR,
+ APR,
+ MAY,
+ JUN,
+ JUL,
+ AUG,
+ SEP,
+ OCT,
+ NOV
+};
+
+void
+caljulian(
+ u_long ntptime,
+ register struct calendar *jt
+ )
+{
+ u_long ntp_day;
+ u_long minutes;
+ /*
+ * Absolute, zero-adjusted Christian era day, starting from the
+ * mythical day 12/1/1 BC
+ */
+ u_long acez_day;
+
+ u_long d400; /* Days into a Gregorian cycle */
+ u_long d100; /* Days into a normal century */
+ u_long d4; /* Days into a 4-year cycle */
+ u_long n400; /* # of Gregorian cycles */
+ u_long n100; /* # of normal centuries */
+ u_long n4; /* # of 4-year cycles */
+ u_long n1; /* # of years into a leap year */
+ /* cycle */
+
+ /*
+ * Do the easy stuff first: take care of hh:mm:ss, ignoring leap
+ * seconds
+ */
+ jt->second = (u_char)(ntptime % SECSPERMIN);
+ minutes = ntptime / SECSPERMIN;
+ jt->minute = (u_char)(minutes % MINSPERHR);
+ jt->hour = (u_char)((minutes / MINSPERHR) % HRSPERDAY);
+
+ /*
+ * Find the day past 1900/01/01 00:00 UTC
+ */
+ ntp_day = ntptime / SECSPERDAY;
+ acez_day = DAY_NTP_STARTS + ntp_day - 1;
+ n400 = acez_day/GREGORIAN_CYCLE_DAYS;
+ d400 = acez_day%GREGORIAN_CYCLE_DAYS;
+ n100 = d400 / GREGORIAN_NORMAL_CENTURY_DAYS;
+ d100 = d400 % GREGORIAN_NORMAL_CENTURY_DAYS;
+ n4 = d100 / GREGORIAN_NORMAL_LEAP_CYCLE_DAYS;
+ d4 = d100 % GREGORIAN_NORMAL_LEAP_CYCLE_DAYS;
+ n1 = d4 / DAYSPERYEAR;
+
+ /*
+ * Calculate the year and year-of-day
+ */
+ jt->yearday = (u_short)(1 + d4%DAYSPERYEAR);
+ jt->year = (u_short)(400*n400 + 100*n100 + n4*4 + n1);
+
+ if (n100 == 4 || n1 == 4)
+ {
+ /*
+ * If the cycle year ever comes out to 4, it must be December 31st
+ * of a leap year.
+ */
+ jt->month = 12;
+ jt->monthday = 31;
+ jt->yearday = 366;
+ }
+ else
+ {
+ /*
+ * Else, search forwards through the months to get the right month
+ * and date.
+ */
+ int monthday;
+
+ jt->year++;
+ monthday = jt->yearday;
+
+ for (jt->month=0;jt->month<11; jt->month++)
+ {
+ int t;
+
+ t = monthday - calmonthtab[jt->month];
+ if (jt->month == 1 && is_leapyear(jt->year))
+ t--;
+
+ if (t > 0)
+ monthday = t;
+ else
+ break;
+ }
+ jt->month++;
+ jt->monthday = monthday;
+ }
+}