1 /* persian calendar functions original code is by Kees Couprie
2 http://www.geocities.com/couprie/calmath/ */
4 /* islamic conversion and moonphase calculation is taken from
8 * Copyright (c) 1992 by Waleed A. Muhanna
10 * Permission for nonprofit use and redistribution of this software and
11 * its documentation is hereby granted without fee, provided that the
12 * above copyright notice appear in all copies and that both that copyright
13 * notice and this permission notice appear in supporting documentation.
15 * No representation is made about the suitability of this software for any
16 * purpose. It is provided "as is" without express or implied warranty.
18 * Send any comments/suggestions/fixes/additions to:
19 * wmuhanna@magnus.acs.ohio-state.edu
23 #include "calendarfunc.h"
28 long persian_jdn(struct icaltimetype dt
)
30 const long PERSIAN_EPOCH
= 1948321; /* The JDN of 1 Farvardin 1*/
35 epbase
= dt
.year
- 474;
36 epyear
= 474 + (epbase
% 2820);
38 mdays
= (dt
.month
- 1) * 31;
40 mdays
= (dt
.month
- 1) * 30 + 6;
41 jdn
= dt
.day
+ mdays
;
42 jdn
+= (((epyear
* 682) - 110) / 2816) ;
43 jdn
+= (epyear
- 1) * 365;
44 jdn
+= (epbase
/ 2820) * 1029983 ;
45 jdn
+= (PERSIAN_EPOCH
- 1);
49 double tmoonphase( long n
, int nph
)
51 double jd
, t
, t2
, t3
, k
, ma
, sa
, tf
, xtra
;
52 k
= n
+ nph
/4.0; t
= k
/1236.85; t2
= t
*t
; t3
= t2
*t
;
53 jd
= 2415020.75933 + 29.53058868*k
- 1.178e-4 * t2
55 + 3.3e-4 * sin (RPD
* (166.56 +132.87*t
-0.009173*t2
));
57 /* Sun's mean anomaly */
58 sa
= RPD
* (359.2242 + 29.10535608*k
- 3.33e-5 * t2
- 3.47e-6 * t3
);
60 /* Moon's mean anomaly */
61 ma
= RPD
* (306.0253 + 385.81691806*k
+ 0.0107306*t2
+1.236e-5 *t3
);
63 /* Moon's argument of latitude */
64 tf
= RPD
* 2.0 * (21.2964 + 390.67050646*k
-0.0016528*t2
67 /* should reduce to interval 0-1.0 before calculating further */
69 /* Corrections for New and Full Moon */
70 xtra
= (0.1734 - 0.000393*t
) * sin(sa
)
72 -0.4068*sin(ma
) +0.0161*sin(2*ma
) -0.0004*sin(3*ma
)
74 -0.0051*sin(sa
+ma
) -0.0074*sin(sa
-ma
)
75 +0.0004*sin(tf
+sa
) -0.0004*sin(tf
-sa
)
76 -0.0006*sin(tf
+ma
) +0.0010*sin(tf
-ma
)
77 +0.0005*sin(sa
+ 2*ma
);
78 else if (nph
==1 || nph
==3) {
79 xtra
= (0.1721 - 0.0004*t
) * sin(sa
)
81 -0.6280*sin(ma
) +0.0089*sin(2*ma
) -0.0004*sin(3*ma
)
83 -0.0119*sin(sa
+ma
) -0.0047*sin(sa
-ma
)
84 +0.0003*sin(tf
+sa
) -0.0004*sin(tf
-sa
)
85 -0.0006*sin(tf
+ma
) +0.0021*sin(tf
-ma
)
86 +0.0003*sin(sa
+ 2*ma
) +0.0004*sin(sa
-2*ma
)
89 xtra
= xtra
+0.0028 -0.0004*cos(sa
) +0.0003*cos(ma
);
91 xtra
= xtra
-0.0028 +0.0004*cos(sa
) -0.0003*cos(ma
);
93 printf("tmoonphase: illegal phase number\n");
96 /* convert from Ephemeris Time (ET) to (approximate)
97 Universal Time (UT) */
98 jd
+= xtra
- (0.41 +1.2053*t
+0.4992*t2
)/1440;
103 double visible(long n
,double * rjd
)
109 jd
= tmoonphase(n
,0);
113 if (tf
<=0.5) /*new moon starts in the afternoon */
115 /* new moon starts before noon */
116 tf
= (tf
-0.5)*24 +TIMZ
; /* local time */
117 if (tf
>TIMDIF
) return(jd
+1.0); /*age at sunset < min for visiblity*/
122 struct icaltimetype
jdn_islamic(long jdn
)
124 struct icaltimetype h
;
128 /* obtain first approx. of how many new moons since the beginning
131 k
= 0.6 + (h
.year
+ ((int) (h
.month
- 0.5)) / 12.0 + h
.day
132 / 365.0 - 1900) * 12.3685;
134 mjd
= visible(k
--, &rjd
);
137 /*first of the month is the following day*/
139 h
.year
= 1405 + (hm
/ 12);
141 h
.month
= (hm
% 12) +1;
142 if (hm
!= 0 && h
.month
<= 0) {
148 h
.day
= jdn
- mjd
+ 1;
154 long islamic_jdn(struct icaltimetype dt
)
159 k
= dt
.month
+ dt
.year
* 12 - NMONTHS
; /* # of m since 1/1/1405 */
160 jd
= visible(k
+ 1048L, &rjd
) + dt
.day
;
167 struct icaltimetype
jdn_persian(long jdn
)
169 struct icaltimetype ret
, h
;
170 int iYear
, iMonth
, iDay
;
180 depoch
= jdn
- persian_jdn(h
);
181 cycle
= depoch
/ 1029983;
182 cyear
= depoch
% 1029983;
183 if( cyear
== 1029982)
188 ycycle
= (((2134 * aux1
) + (2816 * aux2
) + 2815) / 1028522) + aux1
+ 1;
190 iYear
= ycycle
+ (2820 * cycle
) + 474;
194 yday
= (jdn
- persian_jdn(h
)) + 1;
196 iMonth
= Ceil((yday
-1) / 31);
198 iMonth
= Ceil((yday
- 7) / 30);
201 iDay
= (jdn
- persian_jdn(h
)) + 1;
211 int Ceil(float number
)
222 long civil_jdn(struct icaltimetype dt
)
224 long jdn
= ((1461 * (dt
.year
+ 4800 + ((dt
.month
- 14) / 12))) / 4)
225 + ((367 * (dt
.month
- 2 - 12 * (((dt
.month
- 14) / 12)))) / 12)
226 - ((3 * (((dt
.year
+ 4900 + ((dt
.month
- 14) / 12)) / 100))) / 4)
233 struct icaltimetype
jdn_civil(long jdn
)
236 struct icaltimetype ret
;
237 int iday
, imonth
, iyear
;
239 n
= ((4 * l
) / 146097);
240 l
= l
- ((146097 * n
+ 3) / 4);
241 i
= ((4000 * (l
+ 1)) / 1461001);
242 l
= l
- ((1461 * i
) / 4) + 31;
243 j
= ((80 * l
) / 2447);
244 iday
= l
- ((2447 * j
) / 80);
246 imonth
= j
+ 2 - 12 * l
;
247 iyear
= 100 * (n
- 49) + i
+ l
;
259 struct icaltimetype
civil_persian(struct icaltimetype dt
)
261 return(jdn_persian(civil_jdn(dt
)));
265 struct icaltimetype
civil_islamic(struct icaltimetype dt
)
267 return(jdn_islamic(civil_jdn(dt
)));
272 struct icaltimetype
persian_civil(struct icaltimetype dt
)
274 return(jdn_civil(persian_jdn(dt
)));
278 struct icaltimetype
islamic_civil(struct icaltimetype dt
)
280 return(jdn_civil(islamic_jdn(dt
)));
283 struct icaltimetype
get_civil(struct icaltimetype dt
, int calendar
){
286 else if(calendar
== 1)
287 return persian_civil(dt
);
288 else if(calendar
== 2)
289 return islamic_civil(dt
);
294 int isPersianLeap(int year
)
296 struct icaltimetype dt
, dold
;
301 dold
= jdn_civil(2453108);
302 dt
= civil_persian(persian_civil(dt
));
308 int isGregorianLeap(int year
)
312 if(year
% 100 == 0 && year
% 400 != 0)
317 int days_in_month(int month
, int year
, int calendar
)
320 return days_in_gregorian_month(month
, year
);
321 else if(calendar
== 1)
322 return days_in_persian_month(month
, year
);
323 else if(calendar
== 2)
324 return days_in_islamic_month(month
, year
);
329 int days_in_persian_month(int month
, int year
)
335 if(isPersianLeap(year
))
341 int days_in_islamic_month(int month
, int year
)
343 struct icaltimetype dt
, dold
;
352 dt
= jdn_islamic(islamic_jdn(dt
) - 1);
357 int days_in_gregorian_month(int month
, int year
)
366 return 28 + isGregorianLeap(year
);
372 int day_of_week(struct icaltimetype dt
)
380 int moon(struct icaltimetype h
)
382 int k
, jd
, i
,j
, jdn
;
385 if(datemoon
[jd
%200][1] == jd
)
386 return datemoon
[jd
%200][0];
388 k
= 1 + (h
.year
+ ((int) (h
.month
- 0.5)) / 12.0 + h
.day
/ 365.0 - 1900) * 12.3685;
390 mjd
= tmoonphase(k
--, 0);
395 for(i
= tmoonphase(k
,0); i
< tmoonphase(k
+5,0 ); i
++){
396 datemoon
[i
%200][0] = 0;
397 datemoon
[i
%200][1] = i
;
400 for(j
= 0; j
< 6; j
++){
401 for(i
= 0; i
< 4; i
++){
402 mjd
= tmoonphase(k
, i
);
403 datemoon
[mjd
%200][0] = i
+1;
404 datemoon
[mjd
%200][1] = mjd
;
409 if(datemoon
[jd
%200][1] == jd
)
410 return datemoon
[jd
%200][0];
415 int daysComp(struct icaltimetype d1
, struct icaltimetype d2
){
416 if(d1
.year
< d2
.year
)
417 return 1; /* d1 < d2 */
418 if(d1
.year
> d2
.year
)
419 return 2; /* d1 > d2 */
421 /* years are equal */
422 if(d1
.month
< d2
.month
)
423 return 1; /* d1 < d2 */
424 if(d1
.month
> d2
.month
)
425 return 2; /* d1 > d2 */
427 /* months are equal */
429 return 1; /* d1 < d2 */
431 return 2; /* d1 > d2 */
433 return 0; /* days are equal */
437 int daysEqual(struct icaltimetype d1
, struct icaltimetype d2
){
438 if(daysComp(d1
, d2
) == 0)
444 int daysLater(struct icaltimetype d1
, struct icaltimetype d2
){
445 if(daysComp(d1
, d2
) == 1)
451 int daysEarlier(struct icaltimetype d1
, struct icaltimetype d2
){
452 if(daysComp(d1
, d2
) == 2)
458 int daysLaterEqual(struct icaltimetype d1
, struct icaltimetype d2
){
459 if(daysComp(d1
, d2
) != 2)
465 int daysEarlierEqual(struct icaltimetype d1
, struct icaltimetype d2
){
466 if(daysComp(d1
, d2
) != 1)