2 * hdate_hdate.c: convert georgean and hebrew calendars.
5 * Yaacov Zamir <kzamir@walla.co.il>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <https://www.gnu.org/licenses/>.
21 #include <gnumeric-config.h>
26 /* constants, in 1/18th of minute */
30 #define M(h,p) ((h)*HOUR+p)
31 #define MONTH (DAY+M(12,793))
34 @brief Return the days from the start
37 @warning internal function.
40 hdate_days_from_start (int y
)
44 l
= y
* 7 + 1; /* no. of leap months */
45 m
= y
* 12 + l
/ 19; /* total no. of months */
47 nm
= m
* MONTH
+ M (1 + 6, 779); /* molad new year 3744 (16BC) + 6 hours */
48 s
= m
* 28 + nm
/ DAY
- 2;
54 /* special cases of Molad Zaken */
55 if ((l
< 12 && dw
== 3 && nm
>= M (9 + 6, 204)) ||
56 (l
< 7 && dw
== 2 && nm
>= M (15 + 6, 589)))
59 if (dw
== 1 || dw
== 4 || dw
== 6)
65 @brief compute hebrew date from gregorian date
67 @param d Day of month 1..31
68 @param m Month 1..12 , if m or d is 0 return current date.
69 @param y Year in 4 digits e.g. 2001
72 hdate_gdate_to_hdate (int d
, int m
, int y
, int *hd
, int *hm
, int *hy
)
77 if (!(m
>= 1 && m
<= 12) ||
79 && ((y
>= 3000 && m
== 6 && d
<= 59)
80 || (d
<= 31))) || !(y
> 0))
85 jd
= hdate_gdate_to_jd (d
, m
, y
);
87 hdate_jd_to_hdate (jd
, hd
, hm
, hy
);
94 @brief compute general date structure from hebrew date
96 @param d Day of month 1..31
97 @param m Month 0..13 , if m or d is 0 return current date.
98 @param y Year in 4 digits e.g. 5731
100 @attention no sanity cheak !!
103 hdate_hdate_to_gdate (int d
, int m
, int y
, int *gd
, int *gm
, int *gy
)
108 if (!(m
>= 1 && m
<= 12) ||
110 && ((y
>= 3000 && m
== 6 && d
<= 59)
111 || (d
<= 31))) || !(y
> 0))
116 jd
= hdate_hdate_to_jd (d
, m
, y
);
118 hdate_jd_to_gdate (jd
, gd
, gm
, gy
);
124 @brief Compute Julian day (jd from Gregorian day, month and year (d, m, y)
125 Algorithm from 'Julian and Gregorian Day Numbers' by Peter Meyer
126 @author Yaacov Zamir ( algorithm from Henry F. Fliegel and Thomas C. Van Flandern ,1968)
128 @param d Day of month 1..31
130 @param y Year in 4 digits e.g. 2001
133 hdate_gdate_to_jd (int d
, int m
, int y
)
137 jd
= (1461 * (y
+ 4800 + (m
- 14) / 12)) / 4 +
138 (367 * (m
- 2 - 12 * ((m
- 14) / 12))) / 12 -
139 (3 * ((y
+ 4900 + (m
- 14) / 12) / 100)) / 4 + d
- 32075;
145 @brief Converting from the Julian day to the Gregorian day
146 Algorithm from 'Julian and Gregorian Day Numbers' by Peter Meyer
147 @author Yaacov Zamir ( Algorithm, Henry F. Fliegel and Thomas C. Van Flandern ,1968)
150 @param d Return Day of month 1..31
151 @param m Return Month 1..12
152 @param y Return Year in 4 digits e.g. 2001
155 hdate_jd_to_gdate (int jd
, int *d
, int *m
, int *y
)
160 n
= (4 * l
) / 146097;
161 l
= l
- (146097 * n
+ 3) / 4;
162 i
= (4000 * (l
+ 1)) / 1461001; /* that's 1,461,001 */
163 l
= l
- (1461 * i
) / 4 + 31;
165 *d
= l
- (2447 * j
) / 80;
167 *m
= j
+ 2 - (12 * l
);
168 *y
= 100 * (n
- 49) + i
+ l
; /* that's a lower-case L */
172 @brief Converting from the Julian day to the Hebrew day
173 @author Amos Shapir 1984 (rev. 1985, 1992) Yaacov Zamir 2003-2005
176 @param d Return Day of month 1..31
177 @param m Return Month 1..14
178 @param y Return Year in 4 digits e.g. 2001
181 hdate_jd_to_hdate (int jd
, int *d
, int *m
, int *y
)
187 n
= (4 * l
) / 146097;
188 l
= l
- (146097 * n
+ 3) / 4;
189 i
= (4000 * (l
+ 1)) / 1461001; /* that's 1,461,001 */
190 l
= l
- (1461 * i
) / 4 + 31;
193 *y
= 100 * (n
- 49) + i
+ l
; /* that's a lower-case L */
195 *d
= jd
- 1715119; /* julean to days since 1 Tishrei 3744 */
198 s
= hdate_days_from_start (*y
);
199 *m
= hdate_days_from_start (*y
+ 1);
202 { /* computed year was underestimated */
205 *m
= hdate_days_from_start (*y
+ 1);
208 s
= *m
- s
; /* size of current year */
211 /* compute day and month */
213 { /* last 8 months are regular */
216 *d
-= (*m
* 59 + 1) / 2;
218 if (s
> 365 && *m
<= 5) /* Adar of Meuberet */
223 /* first 4 months have 117-119 days */
226 *d
-= (*m
* s
+ 3) / 4;
231 @brief Compute Julian day (jd from Hebrew day, month and year (d, m, y)
232 @author Amos Shapir 1984 (rev. 1985, 1992) Yaacov Zamir 2003-2005
234 @param d Day of month 1..31
236 @param y Year in 4 digits e.g. 5753
239 hdate_hdate_to_jd (int d
, int m
, int y
)
244 s
= hdate_days_from_start (y
);
246 s
= hdate_days_from_start (y
+ 1) - s
; /* length of year */
258 d
+= (59 * (m
- 1) + 1) / 2; /* regular months */
260 if (s
% 10 > 4 && m
> 2) /* long Heshvan */
262 if (s
% 10 < 4 && m
> 3) /* short Kislev */
265 if (s
> 365 && m
> 6) /* leap year */
269 y
= (d
+ 36525) * 4 / 146097 - 1;
270 d
-= y
/ 4 * 146097 + (y
% 4) * 36524;
272 d
+= 1715119; /* days since 1 Tishrei 3744 to julean */