1 /*
2  *	Copyright (c) 1986-2000, Hiram Clawson
3  *	All rights reserved.
4  *
5  *	Redistribution and use in source and binary forms, with or
6  *	without modification, are permitted provided that the following
7  *	conditions are met:
8  *
9  *		Redistributions of source code must retain the above
10  *		copyright notice, this list of conditions and the
11  *		following disclaimer.
12  *
13  *		Redistributions in binary form must reproduce the
14  *		above copyright notice, this list of conditions and
15  *		the following disclaimer in the documentation and/or
16  *		other materials provided with the distribution.
17  *
18  *		Neither name of The Museum of Hiram nor the names of
19  *		its contributors may be used to endorse or promote products
20  *		derived from this software without specific prior
21  *		written permission.
22  *
23  *	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
24  *	CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
25  *	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26  *	MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27  *	IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28  *	INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29  *	(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  *	OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  *	HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32  *	STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
33  *	IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
34  *	THE POSSIBILITY OF SUCH DAMAGE.
35  */
36 
37 #include "astime.h"	/*	time structures	*/
38 
39 /**
40  *	caldat computes the day of the week, the day of the year
41  *	the gregorian (or julian) calendar date and the universal
42  *	time from the julian decimal date.
43  *	for astronomical purposes, The Gregorian calendar reform occurred
44  *	on 15 Oct. 1582.  This is 05 Oct 1582 by the julian calendar.
45 
46  *	Input:	a ut_instant structure pointer, where the j_date element
47  *		has been set. ( = 0 for 01 Jan 4713 B.C. 12 HR UT )
48  *
49  *	output:  will set all the other elements of the structure.
50  *		As a convienence, the function will also return the year.
51  *
52  *	Reference: Astronomial formulae for calculators, meeus, p 23
53  *	from fortran program by F. Espenak - April 1982 Page 277,
54  *	50 Year canon of solar eclipses: 1986-2035
55  *
56  */
57 
caldat(date)58 long caldat( date )
59 struct ut_instant * date;
60 {
61 	double frac;
62 	long jd;
63 	long ka;
64 	long kb;
65 	long kc;
66 	long kd;
67 	long ke;
68 	long ialp;
69 
70 	jd = (long) (date->j_date + 0.5);	/* integer julian date */
71 	frac = date->j_date + 0.5 - (double) jd + 1.0e-10; /* day fraction */
72 	ka = (long) jd;
73 	if ( jd >= 2299161L )
74 	{
75 		ialp = (long) (((double) jd) - 1867216.25 ) / 36524.25;
76 		ka = jd + 1L + ialp - ( ialp >> 2 );
77 	}
78 	kb = ka + 1524L;
79 	kc = (long) ((double) kb - 122.1 ) / 365.25;
80 	kd = (long) (double) kc * 365.25;
81 	ke = (long) (double) ( kb - kd ) / 30.6001;
82 	date->day = kb - kd - ((long) ( (double) ke * 30.6001 ));
83 	if ( ke > 13L )
84 		date->month = ke - 13L;
85 	else
86 		date->month = ke - 1L;
87 	if ( (date->month == 2) && (date->day > 28) )
88 		date->day = 29;
89 	if ( (date->month == 2) && (date->day == 29) && (ke == 3L) )
90 		date->year = kc - 4716L;
91 	else if ( date->month > 2 )
92 		date->year = kc - 4716L;
93 	else
94 		date->year = kc - 4715L;
95 	date->i_hour = date->d_hour = frac * 24.0;	/* hour */
96 	date->i_minute = date->d_minute = (long)
97 		( date->d_hour - (double) date->i_hour ) * 60.0; /* minute */
98 	date->i_second = date->d_second = (long)
99 		( date->d_minute - (double) date->i_minute ) * 60.0;/* second */
100 	date->weekday = (jd + 1L) % 7L;	/* day of week */
101 	if ( date->year == ((date->year >> 2) << 2) )
102 		date->day_of_year =
103 			( ( 275 * date->month ) / 9)
104 			- ((date->month + 9) / 12)
105 			+ date->day - 30;
106 	else
107 		date->day_of_year =
108 			( ( 275 * date->month ) / 9)
109 			- (((date->month + 9) / 12) << 1)
110 			+ date->day - 30;
111 	return( date->year );
112 }
113 
114 /**
115  *	juldat computes the julian decimal date (j_date) from
116  *	the gregorian (or Julian) calendar date.
117  *	for astronomical purposes, The Gregorian calendar reform occurred
118  *	on 15 Oct. 1582.  This is 05 Oct 1582 by the julian calendar.
119  *	Input:  a ut_instant structure pointer where Day, Month, Year and
120  *		i_hour, i_minute, d_second have been set for the date
121  *		in question.
122  *
123  *	Output: the j_date and weekday elements of the structure will be set.
124  *		Also, the return value of the function will be the j_date too.
125  *
126  *	Reference: Astronomial formulae for calculators, meeus, p 23
127  *	from fortran program by F. Espenak - April 1982 Page 276,
128  *	50 Year canon of solar eclipses: 1986-2035
129  */
130 
juldat(date)131 double juldat( date )
132 struct ut_instant * date;
133 {
134 	double frac, gyr;
135 	long iy0, im0;
136 	long ia, ib;
137 	long jd;
138 
139 	/* decimal day fraction	*/
140 	frac = (( double)date->i_hour/ 24.0)
141 		+ ((double) date->i_minute / 1440.0)
142 		+ (date->d_second / 86400.0);
143 	/* convert date to format YYYY.MMDDdd	*/
144 	gyr = (double) date->year
145 		+ (0.01 * (double) date->month)
146 		+ (0.0001 * (double) date->day)
147 		+ (0.0001 * frac) + 1.0e-9;
148 	/* conversion factors */
149 	if ( date->month <= 2 )
150 	{
151 		iy0 = date->year - 1L;
152 		im0 = date->month + 12;
153 	}
154 	else
155 	{
156 		iy0 = date->year;
157 		im0 = date->month;
158 	}
159 	ia = iy0 / 100L;
160 	ib = 2L - ia + (ia >> 2);
161 	/* calculate julian date	*/
162 	if ( date->year < 0L )
163 		jd = (long) ((365.25 * (double) iy0) - 0.75)
164 			+ (long) (30.6001 * (im0 + 1L) )
165 			+ (long) date->day + 1720994L;
166 	else
167 		jd = (long) (365.25 * (double) iy0)
168 			+ (long) (30.6001 * (double) (im0 + 1L))
169 			+ (long) date->day + 1720994L;
170 	if ( gyr >= 1582.1015 )	/* on or after 15 October 1582	*/
171 		jd += ib;
172 	date->j_date = (double) jd + frac + 0.5;
173 	jd = (long) (date->j_date + 0.5);
174 	date->weekday = (jd + 1L) % 7L;
175 	return( date->j_date );
176 }	/*	end of	double juldat( date )	*/
177