// FajrAngle and IshaAngle are based on the 5 different methods of calculating prayer (ISNA, Muslim World League, etc.) public static string find_sun_and_twi_events_for_date(double mjd, double timezone, double longitude, double latitude, double imsaakAngle, double FajrAngle, double IshaAngle, AstroValues astroValues) { double slatitude, mydate, ym, yz, utrise = 0, utset = 0; bool above, rise, sett; // // this is my attempt to encapsulate most of the program in a function // then this function can be generalised to find all the Sun events. double yp, nz, hour, z1 = 0, z2 = 0, iobj, clatitude, rads; rads = 0.0174532925; double[] sinho = new double[6] { Math.Sin(rads * -0.833), // sunset upper limb simple refraction Math.Sin(rads * -4.0), // civil twi Math.Sin(rads * -12.0), // nautical twi // Angle of Sun for Imsaak, Fajr and Isha Math.Sin(rads * FajrAngle), // astro twi (-18.0) Math.Sin(rads * IshaAngle), // astro twi (-18.0) Math.Sin(rads * imsaakAngle) // usually -18 }; string always_up = " ****"; string always_down = " ...."; string outstring = ""; // // Set up the array with the 4 values of sinho needed for the 4 // kinds of sun event // slatitude = Math.Sin(rads * latitude); clatitude = Math.Cos(rads * latitude); mydate = mjd - timezone / 24; // // main loop takes each value of sinho in turn and finds the rise/set // events associated with that altitude of the Sun // for (int j = 0; j <= 5; j++) { rise = false; sett = false; above = false; hour = 1.0; ym = (double)sin_alt(2, mydate, hour - 1.0, longitude, clatitude, slatitude) - sinho[j]; if ((ym > 0.0)) { above = true; } // // the while loop finds the sin(alt) for sets of three consecutive // hours, and then tests for a single zero crossing in the interval // or for two zero crossings in an interval or for a grazing event // The flags rise and sett are set accordingly // while ((hour < 25 & (sett == false || rise == false))) { yz = sin_alt(2, mydate, hour, longitude, clatitude, slatitude) - sinho[j]; yp = sin_alt(2, mydate, hour + 1.0, longitude, clatitude, slatitude) - sinho[j]; // finds the parabola throuh the three points (-1,ym), (0,yz), (1, yp) // and returns the coordinates of the max/min (if any) xe, ye // the values of x where the parabola crosses zero (roots of the quadratic) // and the number of roots (0, 1 or 2) within the interval [-1, 1] // // well, this routine is producing sensible answers // // results passed as array [nz, z1, z2, xe, ye] // double dx; nz = 0; double a = 0.5 * (ym + yp) - yz; double b = 0.5 * (yp - ym); double c = yz; double xe = -b / (2 * a); double ye = (a * xe + b) * xe + c; double dis = b * b - 4.0 * a * c; if ((dis > 0)) { dx = 0.5 * Math.Sqrt(dis) / Math.Abs(a); z1 = xe - dx; z2 = xe + dx; if ((Math.Abs(z1) <= 1.0)) { nz = nz + 1; } if ((Math.Abs(z2) <= 1.0)) { nz = nz + 1; } if ((z1 < -1.0)) { z1 = z2; } } // case when one event is found in the interval if ((nz == 1)) { if ((ym < 0.0)) { utrise = hour + z1; rise = true; } else { utset = hour + z1; sett = true; } } // end of nz = 1 case // case where two events are found in this interval // (rare but whole reason we are not using simple iteration) if ((nz == 2)) { if ((ye < 0.0)) { utrise = hour + z2; utset = hour + z1; } else { utrise = hour + z1; utset = hour + z2; } } // end of nz = 2 case // set up the next search interval ym = yp; hour = hour + 2.0; } // now search has completed, we compile the string to pass back // to the main loop. The string depends on several combinations // of the above flag (always above or always below) and the rise // and sett flags // DateTime cur; if ((rise == true || sett == true)) { if ((rise == true)) { cur = DateTime.Parse(hrsmin(utrise)); } else { cur = DateTime.Parse("1/1/1900"); } if (j == 0) { astroValues.sunset_begin = cur; } else if (j == 1) { astroValues.civil_begin = cur; } else if (j == 2) { astroValues.naut_begin = cur; } else if (j == 3) { astroValues.astro_begin = cur; } else if (j == 4) { } else if (j == 5) { astroValues.imsaak_begin = cur; } // ------------------------------------- if ((sett == true)) { cur = DateTime.Parse(hrsmin(utset)); } else { cur = DateTime.Parse("1/1/1900"); } if (j == 0) { astroValues.sunset_end = cur; } else if (j == 1) { astroValues.civil_end = cur; } else if (j == 2) { astroValues.naut_end = cur; } else if (j == 4) { astroValues.astro_end = cur; } } else if ((above == true)) { outstring = outstring + always_up + always_up; } else { outstring = outstring + always_down + always_down; } } // end of for loop - next condition return(outstring); }
public static PrayerTimes GetPrayerTimes(SchoolsofThought Madhab, PrayerCalculationMethod Calc_Method, DateTime doDate, double longitude, double latitude, double timezone, bool doDayLightSavings) { PrayerTimes prayerTimes = new PrayerTimes(); AstroValues astroValues = new AstroValues(); int myday = doDate.Day; int mymonth = doDate.Month; int myyear = doDate.Year; double mj; double diffMin; DateTime curDate; // // main loop. All the work is done in the functions with the double names // find_sun_and_twi_events_for_date() and find_moonrise_set() // mj = JulianDay(myday, mymonth, myyear, 0); double imsaakAngle; double fajrAngle; double IshaAngle; if (Calc_Method == PrayerCalculationMethod.Karachi) { imsaakAngle = -18; fajrAngle = -18.0; IshaAngle = -18.0; } else if (Calc_Method == PrayerCalculationMethod.ISNA) { imsaakAngle = -18; fajrAngle = -15.0; IshaAngle = -15.0; } else if (Calc_Method == PrayerCalculationMethod.MuslimWorldLeague) { imsaakAngle = -18; fajrAngle = -18.0; IshaAngle = -17.0; } else if (Calc_Method == PrayerCalculationMethod.Egypt) { imsaakAngle = -19.5; fajrAngle = -19.5; IshaAngle = -17.5; } else { imsaakAngle = -18; fajrAngle = -16.0; IshaAngle = -15.0; } // Start Loop here if you want to go through dates astroCalcs.find_sun_and_twi_events_for_date(mj, timezone, longitude, latitude, imsaakAngle, fajrAngle, IshaAngle, astroValues); diffMin = Math.Abs((astroValues.sunset_end - astroValues.sunset_begin).TotalMinutes); curDate = new DateTime(myyear, mymonth, myday); getAsr getAsr = new getAsr(); prayerTimes.Fajr = astroValues.astro_begin; prayerTimes.SunRise = astroValues.sunset_begin; prayerTimes.Dhuhr = astroValues.sunset_begin.AddMinutes(diffMin / 2); // DateAdd("n", diffMin / 2, (DateTime)sunset_begin);; prayerTimes.Isha = astroValues.astro_end; prayerTimes.SalatUlLayl = prayerTimes.Dhuhr.AddHours(12); // add 12 hours to zhuhr; if (Madhab == SchoolsofThought.Hanafi) { prayerTimes.Imsaak = astroValues.imsaak_begin; prayerTimes.Asr = getAsr.CalculateAsr(longitude, latitude, timezone, curDate, prayerTimes.Dhuhr, 2); prayerTimes.Sunset = null; prayerTimes.Maghrib = astroValues.sunset_end; } else if (Madhab == SchoolsofThought.Shaffii) { prayerTimes.Imsaak = astroValues.imsaak_begin; prayerTimes.Asr = getAsr.CalculateAsr(longitude, latitude, timezone, curDate, prayerTimes.Dhuhr, 1); prayerTimes.Sunset = null; prayerTimes.Maghrib = astroValues.sunset_end; } else { prayerTimes.Imsaak = astroValues.imsaak_begin; prayerTimes.Asr = getAsr.CalculateAsr(longitude, latitude, timezone, curDate, prayerTimes.Dhuhr, 1); prayerTimes.Sunset = astroValues.sunset_end; prayerTimes.Maghrib = astroValues.civil_end; //prayerTimes.Midnight = DateAdd(DateInterval.Minute, (DateDiff(DateInterval.Minute, (DateTime)Today + " " + sunset_end, (DateTime)Today.AddDays(1) + " " + astro_begin) / 2), sunset_end); prayerTimes.Midnight = astroValues.sunset_end.AddMinutes((astroValues.astro_begin.AddDays(1) - astroValues.sunset_end).TotalMinutes / 2); } getAsr = null /* TODO Change to default(_) if this is not a reference type */; prayerTimes.Fajr = Convert.ToDateTime(prayerTimes.Fajr); // .AddMinutes(1) prayerTimes.Dhuhr = Convert.ToDateTime(prayerTimes.Dhuhr).AddMinutes(1); prayerTimes.Isha = Convert.ToDateTime(prayerTimes.Isha); // .AddMinutes(1) switch (Calc_Method) { case PrayerCalculationMethod.LevaInstitute: case PrayerCalculationMethod.ISNA: { prayerTimes.Imsaak = astroValues.imsaak_begin; break; } case PrayerCalculationMethod.Karachi: case PrayerCalculationMethod.MuslimWorldLeague: case PrayerCalculationMethod.Saudi: case PrayerCalculationMethod.Egypt: { prayerTimes.Imsaak = astroValues.astro_begin.AddMinutes(-10); break; } } // Apply Daylight Savings time if necessary if (doDayLightSavings) { // DAY LIGHT SAVINGS TIME PART bool do_DST; // Do Day Light savings or not daylightSavings.GetDayLightSavings(myyear, out DateTime beginDST, out DateTime endDST); do_DST = daylightSavings.isDST(beginDST, endDST, mymonth, myday); if (do_DST == true) { prayerTimes.Imsaak = prayerTimes.Imsaak.AddHours(1); prayerTimes.Fajr = prayerTimes.Fajr.AddHours(1); prayerTimes.SunRise = prayerTimes.SunRise.AddHours(1); prayerTimes.Dhuhr = prayerTimes.Dhuhr.AddHours(1); prayerTimes.Asr = prayerTimes.Asr.AddHours(1); if (prayerTimes.Sunset.HasValue) { prayerTimes.Sunset = prayerTimes.Sunset.Value.AddHours(1); } prayerTimes.Maghrib = prayerTimes.Maghrib.AddHours(1); prayerTimes.Isha = prayerTimes.Isha.AddHours(1); prayerTimes.Midnight = prayerTimes.Midnight.AddHours(1); prayerTimes.SalatUlLayl = prayerTimes.SalatUlLayl.AddHours(1); } } return(prayerTimes); } // end of main program