summaryrefslogtreecommitdiffabout
path: root/libical/src/libical/caldate.c
Unidiff
Diffstat (limited to 'libical/src/libical/caldate.c') (more/less context) (ignore whitespace changes)
-rw-r--r--libical/src/libical/caldate.c176
1 files changed, 176 insertions, 0 deletions
diff --git a/libical/src/libical/caldate.c b/libical/src/libical/caldate.c
new file mode 100644
index 0000000..f5554f6
--- a/dev/null
+++ b/libical/src/libical/caldate.c
@@ -0,0 +1,176 @@
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
58long caldat( date )
59struct 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 = ( (double) jd - 1867216.25 ) / ( 36524.25 );
76 ka = jd + 1L + ialp - ( ialp >> 2 );
77 }
78 kb = ka + 1524L;
79 kc = ( (double) kb - 122.1 ) / 365.25;
80 kd = (double) kc * 365.25;
81 ke = (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 =
97 ( date->d_hour - (double) date->i_hour ) * 60.0; /* minute */
98 date->i_second = date->d_second =
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
131double juldat( date )
132struct 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 )*/