cazan.c (5368B)
1 /* See LICENSE file for copyright and license details. */ 2 3 #include <math.h> 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <string.h> 7 #include <time.h> 8 9 #include "config.h" 10 #include "util.h" 11 12 /* macros */ 13 #define PI 3.14159265358979323846 14 #define JUL1970 2440587.5 15 #define SEC_INDAY 86400.0 16 #define SEC_INHOUR 3600.0 17 #define OFFSET 2451545.0 18 19 /* typedef */ 20 /* function declarations */ 21 22 /* global variables */ 23 static const long double p1 = 0.066666666666666666; 24 static const long double to_rad = 0.017453292519943295; 25 static const long double to_deg = 57.295779513082322865; 26 static long double p2, p3; 27 28 /* function implementations */ 29 static void 30 usage(void) 31 { 32 die("usage: cazan -[AaUuv] [-lo longitude] [-la latitude]\n\ 33 [-al altitude] [-tz timezone] [-fa fajr_angle]\n\ 34 [-ia isha_angle] [-am asr_mazhab] [-r ramadan]\n\ 35 options:\n \ 36 -A print all prayers time, 12-hour clock format.\n \ 37 -a print all prayers time.\n \ 38 -U print all prayers time, unix-time format.\n \ 39 -u print next prayer time, unix-time format.\n \ 40 -v print version."); 41 } 42 43 static void 44 convert_sec_double_to_min_hour(double sec, int *hours, int *min) 45 { 46 *hours = sec / SEC_INHOUR; 47 *min = (sec - (*hours * SEC_INHOUR)) / 60; 48 } 49 50 static long double 51 T(long double t) 52 { 53 long double p4, p5; 54 p4 = -1.0 * sin(to_rad * t); 55 p5 = to_deg * (acos((p4 - p3) / p2)); 56 return p1 * p5; 57 } 58 59 int 60 main(int argc, char *argv[]) 61 { 62 int hours, min; 63 char pray_char; 64 time_t now, start_of_day; 65 long double duhr_t, asr_t, maghrib_t, isha_t; 66 long double julian, d, g, e, q, sing, sin2g, sine, cose, L, sinL, cosL; 67 long double RA, D, EqT, duhr, fajr, asr, maghrib, isha; 68 long double fajr_t, p4, p5, p6, p7, A; 69 long double next_prayer; 70 71 72 /* 73 if (argc == 1) 74 goto start; 75 76 if (argc == 2) { 77 if (strncmp("-v", argv[1], 2) == 0) 78 die("cazan-" VERSION); 79 if (strncmp("-a", argv[1], 2) == 0) 80 opt = 'a'; 81 if (strncmp("-A", argv[1], 2) == 0) 82 opt = 'A'; 83 if (strncmp("-U", argv[1], 2) == 0) 84 opt = 'U'; 85 if (strncmp("-u", argv[1], 2) == 0) 86 opt = 'u'; 87 else 88 usage(); 89 goto start; 90 } 91 92 for (i = 1; i < argc; i++) { 93 if (!strcmp(argv[i], "-lo")) { 94 longitude = strtold(argv[++i], NULL); 95 } else if (!strcmp(argv[i], "-la")) { 96 latitude = strtold(argv[++i], NULL); 97 } else if (!strcmp(argv[i], "-al")) { 98 altitude = strtold(argv[++i], NULL); 99 } else if (!strcmp(argv[i], "-tz")) { 100 timezone = strtold(argv[++i], NULL); 101 } else if (!strcmp(argv[i], "-fa")) { 102 fajr_angle = strtold(argv[++i], NULL); 103 } else if (!strcmp(argv[i], "-ia")) { 104 isha_angle = strtold(argv[++i], NULL); 105 } else if (!strcmp(argv[i], "-am")) { 106 asr_mazhab = atoi(argv[++i]); 107 FAIL_IF((asr_mazhab > 2 || asr_mazhab < 1), 108 "asr_mazhab must be 1 or 2"); 109 } else if (!strcmp(argv[i], "-r")) { 110 ramadan = atoi(argv[++i]); 111 } else { 112 usage(); 113 } 114 } 115 116 */ 117 if (argc == 1) 118 goto start; 119 else if (argc == 2 && strncmp("-v", argv[1], 2) == 0) 120 die("cazan-" VERSION); 121 else 122 usage(); 123 124 start: 125 time(&now); 126 start_of_day = now - (now % 86400); 127 julian = (now / SEC_INDAY) + JUL1970; 128 d = julian - OFFSET; 129 g = to_rad * ((d * 0.98560028) + 357.529); 130 e = to_rad * (23.439 - (d * 0.00000036)); 131 q = (d * 0.98564736) + 280.459; 132 sing = 1.915 * sin(g); 133 sin2g = 0.020 * sin(2.0 * g); 134 sine = sin(e); 135 cose = cos(e); 136 L = to_rad * (q + sing + sin2g); 137 sinL = sin(L); 138 cosL = cos(L); 139 RA = to_deg * (atan2(cose * sinL, cosL) / 15.0); 140 D = to_deg * (asin(sine * sinL)); 141 EqT = q / 15.0 - RA; 142 p2 = cos(to_rad * latitude) * cos(to_rad * D); 143 p3 = sin(to_rad * latitude) * sin(to_rad * D); 144 145 /* duhr */ 146 duhr = 12.0 + timezone - EqT - (longitude / 15.0); 147 duhr = duhr - (24 * floor(duhr / 24)); 148 duhr_t = start_of_day + (duhr * 3600); 149 150 /* fajr */ 151 fajr_t = T(fajr_angle); 152 fajr = duhr - fajr_t; 153 fajr_t = start_of_day + (fajr * 3600); 154 155 /* asr */ 156 p4 = tan(to_rad * ((latitude - D))); 157 p5 = atan2(1.0, p4 + asr_mazhab); 158 p6 = sin(p5); 159 p7 = to_deg * (acos((p6 - p3) / p2)); 160 A = p1 * p7; 161 asr = duhr + A; 162 asr = asr - (24 * floor(asr / 24)); 163 asr_t = start_of_day + (asr * 3600); 164 165 /* maghrib */ 166 maghrib = duhr + T(0.8333 + 0.0347 * sqrt(altitude)); 167 maghrib = maghrib - (24 * floor(maghrib / 24)); 168 maghrib_t = start_of_day + (maghrib * 3600); 169 170 /* isha */ 171 if (fajr_angle == 18.5) { /* Umm Al-Qura */ 172 isha = maghrib + (90.0 * 0.016666666666666666); 173 if (ramadan == 1) /* Ramadan Umm Al-Qura */ 174 isha = maghrib + (120.0 * 0.016666666666666666); 175 } else { /* Use isha_angle */ 176 isha = duhr + T(isha_angle); 177 } 178 isha = isha - (24 * floor(isha / 24)); 179 isha_t = start_of_day + (isha * 3600); 180 181 next_prayer = fajr_t - now; 182 183 if (fajr_t > now) { 184 pray_char = 'F'; 185 } else if (duhr_t > now) { 186 pray_char = 'D'; 187 next_prayer = duhr_t - now; 188 } else if (asr_t > now) { 189 pray_char = 'A'; 190 next_prayer = asr_t - now; 191 } else if (maghrib_t > now) { 192 pray_char = 'M'; 193 next_prayer = maghrib_t - now; 194 } else if (isha_t > now) { 195 pray_char = 'I'; 196 next_prayer = isha_t - now; 197 } else { 198 pray_char = '?'; 199 } 200 201 /* 202 printf("now\t\t%ld\n", now); 203 printf("fajr_t\t\t%.18Lf\n", fajr_t); 204 printf("duhr_t\t\t%.18Lf\n", duhr_t); 205 printf("asr_t\t\t%.18Lf\n", asr_t); 206 printf("maghrib_t\t%.18Lf\n", maghrib_t); 207 printf("isha_t\t\t%.18Lf\n", isha_t); 208 */ 209 210 convert_sec_double_to_min_hour(next_prayer, &hours, &min); 211 printf("%c %.2d:%.2d\n", pray_char, hours, min); 212 213 return 0; 214 }