public static void Calculate_Soltices_Equinoxes(DateTime d, Celestial c, double offset) { double springEquinoxJDE; double fallEquinoxJDE; double summerSolsticeJDE; double winterSolsticeJDE; //Table 27A if (d.Year <= 1000) { double Y = d.Year / 1000.0; //Determine if actual int springEquinoxJDE = 1721139.29189 + 365242.13740 * Y + 0.06134 * Math.Pow(Y, 2) + 0.00111 * Math.Pow(Y, 3) - 0.00071 * Math.Pow(Y, 4); fallEquinoxJDE = 1721325.70455 + 365242.49558 * Y + 0.11677 * Math.Pow(Y, 2) + 0.00297 * Math.Pow(Y, 3) - 0.00074 * Math.Pow(Y, 4); summerSolsticeJDE = 1721233.25401 + 365241.72562 * Y + 0.05323 * Math.Pow(Y, 2) + 0.00907 * Math.Pow(Y, 3) - 0.00025 * Math.Pow(Y, 4); winterSolsticeJDE = 1721414.39987 + 365242.88257 * Y + 0.00769 * Math.Pow(Y, 2) + 0.00933 * Math.Pow(Y, 3) - 0.00006 * Math.Pow(Y, 4); } //Table 27B else { double Y = (d.Year - 2000) / 1000.0; //Determine if actual in springEquinoxJDE = 2451623.80984 + 365242.37404 * Y + 0.05169 * Math.Pow(Y, 2) + 0.00411 * Math.Pow(Y, 3) - 0.00057 * Math.Pow(Y, 4); fallEquinoxJDE = 2451810.21715 + 365242.01767 * Y + 0.11575 * Math.Pow(Y, 2) + 0.00337 * Math.Pow(Y, 3) - 0.00078 * Math.Pow(Y, 4); summerSolsticeJDE = 2451716.56767 + 365241.62603 * Y + 0.00325 * Math.Pow(Y, 2) + 0.00888 * Math.Pow(Y, 3) - 0.00030 * Math.Pow(Y, 4); winterSolsticeJDE = 2451900.05952 + 365242.74049 * Y + 0.06233 * Math.Pow(Y, 2) + 0.00823 * Math.Pow(Y, 3) - 0.00032 * Math.Pow(Y, 4); } c.Solstices.Summer = Get_Soltice_Equinox_From_JDE0(summerSolsticeJDE, offset); c.Solstices.Winter = Get_Soltice_Equinox_From_JDE0(winterSolsticeJDE, offset); c.Equinoxes.Spring = Get_Soltice_Equinox_From_JDE0(springEquinoxJDE, offset); c.Equinoxes.Fall = Get_Soltice_Equinox_From_JDE0(fallEquinoxJDE, offset); }
/// <summary> /// Creates a Celestial object based on the location and date in the provided Coordinate object /// </summary> /// <param name="c">Coordinate</param> /// <returns>A populated Celestial object</returns> public static Celestial LoadCelestial(Coordinate c) { DateTime geoDate = c.GeoDate; DateTime d = new DateTime(geoDate.Year, geoDate.Month, geoDate.Day, geoDate.Hour, geoDate.Minute, geoDate.Second, DateTimeKind.Utc); Celestial cel = new Celestial(c.Latitude.ToDouble(), c.Longitude.ToDouble(), c.GeoDate); return(cel); }
/// <summary> /// Calculate moon data based on lat/long and date /// </summary> /// <param name="lat">Decimal format latitude</param> /// <param name="longi">Decimal format longitude</param> /// <param name="date">Geographic DateTime</param> /// <returns>Partially populated Celestial Object</returns> public static Celestial CalculateMoonData(double lat, double longi, DateTime date) { Celestial c = new Celestial(false); MoonCalc.GetMoonTimes(date, lat, longi, c); MoonCalc.GetMoonIllumination(date, c); return(c); }
/// <summary> /// Calculate sun data based on lat/long and date /// </summary> /// <param name="lat">Decimal format latitude</param> /// <param name="longi">Decimal format longitude</param> /// <param name="date">Geographic DateTime</param> /// <returns>Partially populated Celestial Object</returns> public static Celestial CalculateSunData(double lat, double longi, DateTime date) { Celestial c = new Celestial(false); SunCalc.CalculateSunTime(lat, longi, date, c); return(c); }
/// <summary> /// Converts Celestial values to local times. /// </summary> /// <param name="c">Coordinate</param> /// <param name="offset">UTC offset</param> /// <returns></returns> public static Celestial Celestial_LocalTime(Coordinate c, double offset) { if (offset < -12 || offset > 12) { throw new ArgumentOutOfRangeException("Time offsets cannot be greater 12 or less than -12."); } //Probably need to offset initial UTC date so user can op in local //Determine best way to do this. DateTime d = c.GeoDate.AddHours(offset); //Get 3 objects for comparison Celestial cel = new Celestial(c.Latitude.ToDouble(), c.Longitude.ToDouble(), c.GeoDate); Celestial celPre = new Celestial(c.Latitude.ToDouble(), c.Longitude.ToDouble(), c.GeoDate.AddDays(-1)); Celestial celPost = new Celestial(c.Latitude.ToDouble(), c.Longitude.ToDouble(), c.GeoDate.AddDays(1)); //Slip objects for comparison. Compare with slipped date. celPre.Local_Convert(c, offset); cel.Local_Convert(c, offset); celPost.Local_Convert(c, offset); //Get SunSet int i = Determine_Slipped_Event_Index(cel.SunSet, celPre.SunSet, celPost.SunSet, d); cel.SunSet = Get_Correct_Slipped_Date(cel.SunSet, celPre.SunSet, celPost.SunSet, i); cel.AdditionalSolarTimes.CivilDusk = Get_Correct_Slipped_Date(cel.AdditionalSolarTimes.CivilDusk, celPre.AdditionalSolarTimes.CivilDusk, celPost.AdditionalSolarTimes.CivilDusk, i); cel.AdditionalSolarTimes.NauticalDusk = Get_Correct_Slipped_Date(cel.AdditionalSolarTimes.NauticalDusk, celPre.AdditionalSolarTimes.NauticalDusk, celPost.AdditionalSolarTimes.NauticalDusk, i); //Get SunRise i = Determine_Slipped_Event_Index(cel.SunRise, celPre.SunRise, celPost.SunRise, d); cel.SunRise = Get_Correct_Slipped_Date(cel.SunRise, celPre.SunRise, celPost.SunRise, i); cel.AdditionalSolarTimes.CivilDawn = Get_Correct_Slipped_Date(cel.AdditionalSolarTimes.CivilDawn, celPre.AdditionalSolarTimes.CivilDawn, celPost.AdditionalSolarTimes.CivilDawn, i); cel.AdditionalSolarTimes.NauticalDawn = Get_Correct_Slipped_Date(cel.AdditionalSolarTimes.NauticalDawn, celPre.AdditionalSolarTimes.NauticalDawn, celPost.AdditionalSolarTimes.NauticalDawn, i); //MoonRise i = Determine_Slipped_Event_Index(cel.MoonRise, celPre.MoonRise, celPost.MoonRise, d); cel.MoonRise = Get_Correct_Slipped_Date(cel.MoonRise, celPre.MoonRise, celPost.MoonRise, i); //MoonSet i = Determine_Slipped_Event_Index(cel.MoonSet, celPre.MoonSet, celPost.MoonSet, d); cel.MoonSet = Get_Correct_Slipped_Date(cel.MoonSet, celPre.MoonSet, celPost.MoonSet, i); //Local Conditions CelestialStatus[] cels = new CelestialStatus[] { celPre.MoonCondition, cel.MoonCondition, celPost.MoonCondition }; cel.MoonCondition = Celestial.GetStatus(cel.MoonRise, cel.MoonSet, cels); cels = new CelestialStatus[] { celPre.SunCondition, cel.SunCondition, celPost.SunCondition }; cel.SunCondition = Celestial.GetStatus(cel.SunRise, cel.SunSet, cels); return(cel); }
public static void GetMoonDistance(DateTime date, Celestial c) { date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, DateTimeKind.Utc); double d = toDays(date); CelCoords cel = GetMoonCoords(d, c); c.MoonDistance = cel.dist; }
/// <summary> /// Calculate sun data based on latitude, longitude and UTC date at the location. /// </summary> /// <param name="lat">latitude</param> /// <param name="longi">longitude</param> /// <param name="date">DateTime</param> /// <returns>Celestial (Partially Populated)</returns> /// <example> /// The following example demonstrates how to create a partially populated Celestial object /// that only calculates solar data using static functions. /// <code> /// //Get Celestial data at N 39, W 72 on 19-Mar-2019 10:10:12 UTC /// Celestial cel = Celestial.CalculateSunData(39, -72, new DateTime(2019, 3, 19, 10, 10, 12)); /// /// Console.WriteLine(cel.SunRise); //3/19/2019 10:54:50 AM /// </code> /// </example> public static Celestial CalculateSunData(double lat, double longi, DateTime date) { date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, DateTimeKind.Utc); Celestial c = new Celestial(false); SunCalc.CalculateSunTime(lat, longi, date, c, new EagerLoad()); SunCalc.CalculateZodiacSign(date, c); return(c); }
/// <summary> /// Calculate moon data based on lat/long and date /// </summary> /// <param name="lat">Decimal format latitude</param> /// <param name="longi">Decimal format longitude</param> /// <param name="date">Geographic DateTime</param> /// <returns>Partially populated Celestial object</returns> public static Celestial CalculateMoonData(double lat, double longi, DateTime date) { date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, DateTimeKind.Utc); Celestial c = new Celestial(false); MoonCalc.GetMoonTimes(date, lat, longi, c); MoonCalc.GetMoonDistance(date, c); MoonCalc.GetMoonSign(date, c); MoonCalc.GetMoonIllumination(date, c, lat, longi); return(c); }
/// <summary> /// Calculate celestial data based on lat/long and utc date /// </summary> /// <param name="lat">Decimal format latitude</param> /// <param name="longi">Decimal format longitude</param> /// <param name="date">Geographic DateTime</param> /// <returns>Fully populated Celestial object</returns> public static Celestial CalculateCelestialTimes(double lat, double longi, DateTime date) { date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, DateTimeKind.Utc); Celestial c = new Celestial(false); SunCalc.CalculateSunTime(lat, longi, date, c); MoonCalc.GetMoonTimes(date, lat, longi, c); MoonCalc.GetMoonDistance(date, c); SunCalc.CalculateZodiacSign(date, c); MoonCalc.GetMoonSign(date, c); MoonCalc.GetMoonIllumination(date, c); SunCalc.CalculateAdditionSolarTimes(date, longi, lat, c); return(c); }
public static Celestial CalculateMoonData(double lat, double longi, DateTime date) { date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, DateTimeKind.Utc); Celestial c = new Celestial(false); MoonCalc.GetMoonTimes(date, lat, longi, c, 0); MoonCalc.GetMoonDistance(date, c); MoonCalc.GetMoonSign(date, c); MoonCalc.GetMoonIllumination(date, c, lat, longi, new EagerLoad(), 0); c.perigee = MoonCalc.GetPerigeeEvents(date); c.apogee = MoonCalc.GetApogeeEvents(date); return(c); }
/// <summary> /// Creates a Coordinate object with default values and a custom datum. /// </summary> /// <remarks> /// Default Coordinate objects will initialize with a latitude and longitude of 0 degrees, /// a GeoDate of 1900-1-1 00:00:00. All properties will be set to EagerLoaded. /// </remarks> internal Coordinate(double equatorialRadius, double inverseFlattening, bool t) { FormatOptions = new CoordinateFormatOptions(); geoDate = new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc); latitude = new CoordinatePart(CoordinateType.Lat); longitude = new CoordinatePart(CoordinateType.Long); latitude.parent = this; longitude.parent = this; celestialInfo = new Celestial(); utm = new UniversalTransverseMercator(latitude.ToDouble(), longitude.ToDouble(), this, equatorialRadius, inverseFlattening); mgrs = new MilitaryGridReferenceSystem(utm); cartesian = new Cartesian(this); ecef = new ECEF(this); EagerLoadSettings = new EagerLoad(); Set_Datum(equatorialRadius, inverseFlattening); }
static CelCoords GetMoonCoords(double d, Celestial c) { // geocentric ecliptic coordinates of the moon //Formulas used from http://aa.quae.nl/en/reken/hemelpositie.html#1_3 double L = rad * (218.316 + 13.176396 * d), // ecliptic longitude M = rad * (134.963 + 13.064993 * d), // mean anomaly F = rad * (93.272 + 13.229350 * d), // mean distance l = L + rad * 6.289 * Math.Sin(M), // longitude b = rad * 5.128 * Math.Sin(F), // latitude dt = 385001 - 20905 * Math.Cos(M); // distance to the moon in km //c.MoonSign = MoonSign(l); CelCoords mc = new CelCoords(); mc.ra = rightAscension(l, b); mc.dec = declination(l, b); mc.dist = dt; return(mc); }
public static void GetMoonIllumination(DateTime date, Celestial c) { date = new DateTime(date.Year, date.Month, date.Day, 0, 0, 0, DateTimeKind.Utc); double d = toDays(date); CelCoords s = GetSunCoords(d); CelCoords m = GetMoonCoords(d); double sdist = 149598000, phi = Math.Acos(Math.Sin(s.dec) * Math.Sin(m.dec) + Math.Cos(s.dec) * Math.Cos(m.dec) * Math.Cos(s.ra - m.ra)), inc = Math.Atan2(sdist * Math.Sin(phi), m.dist - sdist * Math.Cos(phi)), angle = Math.Atan2(Math.Cos(s.dec) * Math.Sin(s.ra - m.ra), Math.Sin(s.dec) * Math.Cos(m.dec) - Math.Cos(s.dec) * Math.Sin(m.dec) * Math.Cos(s.ra - m.ra)); MoonIllum mi = new MoonIllum(); mi.Fraction = (1 + Math.Cos(inc)) / 2; mi.Phase = 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI; mi.Angle = angle; c.MoonPhase = mi.Phase; }
/// <summary> /// Converts lunar time values to local time. /// </summary> /// <param name="coord">Coordinate</param> /// <param name="offset">UTC offset</param> /// <returns>Celestial</returns> /// <example> /// The following example demonstrates how to get Celestial, lunar time only values in Local time. /// DateTime offsets are done manually for readability purposes of this example. /// <code> /// //Local time /// DateTime d = new DateTime(2018, 3, 19, 6, 56, 0, 0, DateTimeKind.Local); /// /// //EST Time is -4 hours from UTC /// double offset = -4; /// /// //Convert the date to UTC time /// d = d.AddHours(offset*-1); /// /// //Create a Coordinate with the UTC time /// Coordinate c = new Coordinate(39.0000, -72.0000, d); /// //Create a new Celestial object by converting the existing one to Local /// Celestial celestial = Celestial.Lunar_LocalTime(c, offset); /// /// Console.WriteLine(celestial.IsMoonUp); //False /// Console.WriteLine(celestial.SunRise); //3/19/2018 08:17 AM /// </code> /// </example> public static Celestial Lunar_LocalTime(Coordinate coord, double offset) { if (offset < -12 || offset > 12) { throw new ArgumentOutOfRangeException("Time offsets cannot be greater 12 or less than -12."); } //Probably need to offset initial UTC date so user can op in local //Determine best way to do this. DateTime d = coord.GeoDate.AddHours(offset); //Get 3 objects for comparison Celestial cel = CalculateMoonData(coord.Latitude.ToDouble(), coord.Longitude.ToDouble(), coord.GeoDate); Celestial celPre = CalculateMoonData(coord.Latitude.ToDouble(), coord.Longitude.ToDouble(), coord.GeoDate.AddDays(-1)); Celestial celPost = CalculateMoonData(coord.Latitude.ToDouble(), coord.Longitude.ToDouble(), coord.GeoDate.AddDays(1)); //Slip objects for comparison. Compare with slipped date. celPre.Local_Convert(coord, offset, Celestial_EagerLoad.Lunar); cel.Local_Convert(coord, offset, Celestial_EagerLoad.Lunar); celPost.Local_Convert(coord, offset, Celestial_EagerLoad.Lunar); //MoonRise int i = Determine_Slipped_Event_Index(cel.MoonRise, celPre.MoonRise, celPost.MoonRise, d); cel.moonRise = Get_Correct_Slipped_Date(cel.MoonRise, celPre.MoonRise, celPost.MoonRise, i); //MoonSet i = Determine_Slipped_Event_Index(cel.MoonSet, celPre.MoonSet, celPost.MoonSet, d); cel.moonSet = Get_Correct_Slipped_Date(cel.MoonSet, celPre.MoonSet, celPost.MoonSet, i); //Local Conditions CelestialStatus[] cels = new CelestialStatus[] { celPre.MoonCondition, cel.MoonCondition, celPost.MoonCondition }; cel.moonCondition = Celestial.GetStatus(cel.MoonRise, cel.MoonSet, cels); //Load IsUp values based on local time with populated Celestial Celestial.Calculate_Celestial_IsUp_Booleans(d, cel); return(cel); }
private static CelCoords GetMoonCoords(double d, Celestial c, double[] LDMNF, double t) { // Legacy function. Updated with Meeus Calcs for increased accuracy. // geocentric ecliptic coordinates of the moon // Meeus Ch 47 double[] cs = Get_Moon_Coordinates(LDMNF, t); double l = cs[0]; // longitude double b = cs[1]; // latitude CelCoords mc = new CelCoords(); mc.ra = rightAscension(l, b); double ra = mc.ra / Math.PI * 180; mc.dec = declination(l, b); double dec = mc.dec / Math.PI * 180; return(mc); }
/// <summary> /// Calculate celestial data based on lat/long and date. /// </summary> /// <param name="lat">Decimal format latitude</param> /// <param name="longi">Decimal format longitude</param> /// <param name="date">Geographic DateTime</param> /// <returns>Fully populated Celestial object</returns> public static Celestial CalculateCelestialTimes(double lat, double longi, DateTime date) { date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, DateTimeKind.Utc); Celestial c = new Celestial(false); SunCalc.CalculateSunTime(lat, longi, date, c); MoonCalc.GetMoonTimes(date, lat, longi, c); MoonCalc.GetMoonDistance(date, c); SunCalc.CalculateZodiacSign(date, c); MoonCalc.GetMoonSign(date, c); MoonCalc.GetMoonIllumination(date, c, lat, longi); c.perigee = MoonCalc.GetPerigeeEvents(date); c.apogee = MoonCalc.GetApogeeEvents(date); Calculate_Celestial_IsUp_Booleans(date, c); return(c); }
/// <summary> /// Gets times for additional solar times /// </summary> private static void getTimes(DateTime date, double lng, double lat, Celestial c) { //Get Julian double d = JulianConversions.GetJulian(date) - j2000 + .5; //LESS PRECISE JULIAN NEEDED double lw = rad * -lng; double phi = rad * lat; double n = julianCycle(d, lw); double ds = approxTransit(0, lw, n); double M = solarMeanAnomaly(ds); double L = eclipticLongitude(M); double dec = declination(L, 0); double Jnoon = solarTransitJ(ds, M, L); double Jset; double Jrise; DateTime?solarNoon = JulianConversions.GetDate_FromJulian(Jnoon); DateTime?nadir = JulianConversions.GetDate_FromJulian(Jnoon - 0.5); c.AdditionalSolarTimes = new AdditionalSolarTimes(); //Dusk and Dawn Jset = GetTime(-6 * rad, lw, phi, dec, n, M, L); Jrise = Jnoon - (Jset - Jnoon); c.AdditionalSolarTimes.CivilDawn = DayMatch(JulianConversions.GetDate_FromJulian(Jrise), date); c.AdditionalSolarTimes.CivilDusk = DayMatch(JulianConversions.GetDate_FromJulian(Jset), date); Jset = GetTime(-12 * rad, lw, phi, dec, n, M, L); Jrise = Jnoon - (Jset - Jnoon); c.AdditionalSolarTimes.NauticalDawn = DayMatch(JulianConversions.GetDate_FromJulian(Jrise), date); c.AdditionalSolarTimes.NauticalDusk = DayMatch(JulianConversions.GetDate_FromJulian(Jset), date); }
static MoonPosition GetMoonPosition(DateTime date, double lat, double lng, Celestial cel) { date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, DateTimeKind.Utc); double d = toDays(date); CelCoords c = GetMoonCoords(d, cel); double lw = rad * -lng; double phi = rad * lat; double H = siderealTime(d, lw) - c.ra; double h = altitude(H, phi, c.dec); // formula 14.1 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998. double pa = Math.Atan2(Math.Sin(H), Math.Tan(phi) * Math.Cos(c.dec) - Math.Sin(c.dec) * Math.Cos(H)); h = h + astroRefraction(h); // altitude correction for refraction MoonPosition mp = new MoonPosition(); mp.Azimuth = azimuth(H, phi, c.dec); mp.Altitude = h; mp.Distance = c.dist; mp.ParallacticAngle = pa; return(mp); }
public static void CalculateSolarEclipse(DateTime date, double lat, double longi, Celestial c) { //Convert to Radian double latR = lat * Math.PI / 180; double longR = longi * Math.PI / 180; List <List <string> > se = SolarEclipseCalc.CalculateSolarEclipse(date, latR, longR); //RETURN FIRST AND LAST if (se.Count == 0) { return; } //FIND LAST AND NEXT ECLIPSE int lastE = -1; int nextE = -1; int currentE = 0; DateTime lastDate = new DateTime(); DateTime nextDate = new DateTime(3300, 1, 1); //Iterate to get last and next eclipse foreach (List <string> values in se) { DateTime ld = DateTime.ParseExact(values[0], "yyyy-MMM-dd", System.Globalization.CultureInfo.InvariantCulture); if (ld < date && ld > lastDate) { lastDate = ld; lastE = currentE; } if (ld >= date && ld < nextDate) { nextDate = ld; nextE = currentE; } currentE++; } //SET ECLIPSE DATA if (lastE >= 0) { c.SolarEclipse.LastEclipse = new SolarEclipseDetails(se[lastE]); } if (nextE >= 0) { c.SolarEclipse.NextEclipse = new SolarEclipseDetails(se[nextE]); } }
public static void CalculateZodiacSign(DateTime date, Celestial c) { //Aquarius (January 20 to February 18) //Pisces (February 19 to March 20) //Aries (March 21-April 19) //Taurus (April 20-May 20) //Gemini (May 21-June 20) //Cancer (June 21-July 22) //Leo (July 23-August 22) //Virgo (August 23-September 22) //Libra (September 23-October 22) //Scorpio (October 23-November 21) //Sagittarius (November 22-December 21) //Capricorn (December 22-January 19) if (date >= new DateTime(date.Year, 1, 1) && date <= new DateTime(date.Year, 1, 19, 23, 59, 59)) { c.AstrologicalSigns.ZodiacSign = "Capricorn"; return; } if (date >= new DateTime(date.Year, 1, 20) && date <= new DateTime(date.Year, 2, 18, 23, 59, 59)) { c.AstrologicalSigns.ZodiacSign = "Aquarius"; return; } if (date >= new DateTime(date.Year, 2, 19) && date <= new DateTime(date.Year, 3, 20, 23, 59, 59)) { c.AstrologicalSigns.ZodiacSign = "Pisces"; return; } if (date >= new DateTime(date.Year, 3, 21) && date <= new DateTime(date.Year, 4, 19, 23, 59, 59)) { c.AstrologicalSigns.ZodiacSign = "Aries"; return; } if (date >= new DateTime(date.Year, 4, 20) && date <= new DateTime(date.Year, 5, 20, 23, 59, 59)) { c.AstrologicalSigns.ZodiacSign = "Taurus"; return; } if (date >= new DateTime(date.Year, 5, 21) && date <= new DateTime(date.Year, 6, 20, 23, 59, 59)) { c.AstrologicalSigns.ZodiacSign = "Gemini"; return; } if (date >= new DateTime(date.Year, 6, 21) && date <= new DateTime(date.Year, 7, 22, 23, 59, 59)) { c.AstrologicalSigns.ZodiacSign = "Cancer"; return; } if (date >= new DateTime(date.Year, 7, 23) && date <= new DateTime(date.Year, 8, 22, 23, 59, 59)) { c.AstrologicalSigns.ZodiacSign = "Leo"; return; } if (date >= new DateTime(date.Year, 8, 23) && date <= new DateTime(date.Year, 9, 22, 23, 59, 59)) { c.AstrologicalSigns.ZodiacSign = "Virgo"; return; } if (date >= new DateTime(date.Year, 9, 23) && date <= new DateTime(date.Year, 10, 22, 23, 59, 59)) { c.AstrologicalSigns.ZodiacSign = "Libra"; return; } if (date >= new DateTime(date.Year, 9, 23) && date <= new DateTime(date.Year, 11, 21, 23, 59, 59)) { c.AstrologicalSigns.ZodiacSign = "Scorpio"; return; } if (date >= new DateTime(date.Year, 11, 21) && date <= new DateTime(date.Year, 12, 21, 23, 59, 59)) { c.AstrologicalSigns.ZodiacSign = "Sagittarius"; return; } if (date >= new DateTime(date.Year, 12, 22) && date <= new DateTime(date.Year, 12, 31, 23, 59, 59)) { c.AstrologicalSigns.ZodiacSign = "Capricorn"; return; } }
private static void CalculateSunAngle(DateTime date, double longi, double lat, Celestial c, SolarCoordinates solC) { double[] ang = CalculateSunAngle(date, longi, lat, solC); c.sunAzimuth = ang[0]; c.sunAltitude = ang[1]; }
public static void CalculateSunTime(double lat, double longi, DateTime date, Celestial c, EagerLoad el, double offset) { if (date.Year == 0001) { return; } //Return if date value hasn't been established. if (el.Extensions.Solar_Cycle) { DateTime actualDate = new DateTime(date.Year, date.Month, date.Day, 0, 0, 0, DateTimeKind.Utc); ////Sun Time Calculations //Get solar coordinate info and feed //Get Julian double lw = rad * -longi; double phi = rad * lat; //Rise Set DateTime?[] evDate = Get_Event_Time(lw, phi, -.8333, actualDate, offset, true); //ADDED OFFSET TO ALL Get_Event_Time calls. c.sunRise = evDate[0]; c.sunSet = evDate[1]; c.solarNoon = evDate[2]; c.sunCondition = CelestialStatus.RiseAndSet; //Get Solar Coordinate var celC = Get_Solar_Coordinates(date, -offset); c.solarCoordinates = celC; //Azimuth and Altitude CalculateSunAngle(date.AddHours(-offset), longi, lat, c, celC); //SUBTRACT OFFSET TO CALC IN Z TIME AND ADJUST SUN ANGLE DURING LOCAL CALCULATIONS. // neither sunrise nor sunset if ((!c.SunRise.HasValue) && (!c.SunSet.HasValue)) { if (c.SunAltitude < 0) { c.sunCondition = CelestialStatus.DownAllDay; } else { c.sunCondition = CelestialStatus.UpAllDay; } } // sunrise or sunset else { if (!c.SunRise.HasValue) { // No sunrise this date c.sunCondition = CelestialStatus.NoRise; } else if (!c.SunSet.HasValue) { // No sunset this date c.sunCondition = CelestialStatus.NoSet; } } //Additional Times c.additionalSolarTimes = new AdditionalSolarTimes(); //Dusk and Dawn //Civil evDate = Get_Event_Time(lw, phi, -6, actualDate, offset, false); c.AdditionalSolarTimes.civilDawn = evDate[0]; c.AdditionalSolarTimes.civilDusk = evDate[1]; //Nautical evDate = Get_Event_Time(lw, phi, -12, actualDate, offset, false); c.AdditionalSolarTimes.nauticalDawn = evDate[0]; c.AdditionalSolarTimes.nauticalDusk = evDate[1]; //Astronomical evDate = Get_Event_Time(lw, phi, -18, actualDate, offset, false); c.AdditionalSolarTimes.astronomicalDawn = evDate[0]; c.AdditionalSolarTimes.astronomicalDusk = evDate[1]; //BottomDisc evDate = Get_Event_Time(lw, phi, -.2998, actualDate, offset, false); c.AdditionalSolarTimes.sunriseBottomDisc = evDate[0]; c.AdditionalSolarTimes.sunsetBottomDisc = evDate[1]; } if (el.Extensions.Solstice_Equinox) { Calculate_Soltices_Equinoxes(date, c, offset); } if (el.Extensions.Solar_Eclipse) { CalculateSolarEclipse(date, lat, longi, c); } }
/// <summary> /// Set boolean SunIsUp and MoonIsUp values /// </summary> /// <param name="date">Coordinate GeoDate</param> /// <param name="cel">Celestial Object</param> private static void Calculate_Celestial_IsUp_Booleans(DateTime date, Celestial cel) { //SUN switch (cel.SunCondition) { case CelestialStatus.DownAllDay: cel.isSunUp = false; break; case CelestialStatus.UpAllDay: cel.isSunUp = true; break; case CelestialStatus.NoRise: if (date < cel.SunSet) { cel.isSunUp = true; } else { cel.isSunUp = false; } break; case CelestialStatus.NoSet: if (date > cel.SunRise) { cel.isSunUp = true; } else { cel.isSunUp = false; } break; case CelestialStatus.RiseAndSet: if (cel.SunRise < cel.SunSet) { if (date > cel.SunRise && date < cel.SunSet) { cel.isSunUp = true; } else { cel.isSunUp = false; } } else { if (date > cel.SunRise || date < cel.SunSet) { cel.isSunUp = true; } else { cel.isSunUp = false; } } break; default: //Should never be reached unless intended null. If reached, previous calculations failed somewhere. break; } //MOON switch (cel.MoonCondition) { case CelestialStatus.DownAllDay: cel.isMoonUp = false; break; case CelestialStatus.UpAllDay: cel.isMoonUp = true; break; case CelestialStatus.NoRise: if (date < cel.MoonSet) { cel.isMoonUp = true; } else { cel.isMoonUp = false; } break; case CelestialStatus.NoSet: if (date > cel.MoonRise) { cel.isMoonUp = true; } else { cel.isMoonUp = false; } break; case CelestialStatus.RiseAndSet: if (cel.MoonRise < cel.MoonSet) { if (date > cel.MoonRise && date < cel.MoonSet) { cel.isMoonUp = true; } else { cel.isMoonUp = false; } } else { if (date > cel.MoonRise || date < cel.MoonSet) { cel.isMoonUp = true; } else { cel.isMoonUp = false; } } break; default: //Should never be reached unless intended null. If reached, previous calculations failed somewhere. break; } }
public static void CalculateLunarEclipse(DateTime date, double lat, double longi, Celestial c) { //Convert to Radian double latR = lat * Math.PI / 180; double longR = longi * Math.PI / 180; List <List <string> > se = LunarEclipseCalc.CalculateLunarEclipse(date, latR, longR); //RETURN FIRST AND LAST if (se.Count == 0) { return; } //FIND LAST AND NEXT ECLIPSE int lastE = -1; int nextE = -1; int currentE = 0; DateTime lastDate = new DateTime(); DateTime nextDate = new DateTime(3300, 1, 1); //Iterate to get last and next eclipse foreach (List <string> values in se) { DateTime ld = Convert.ToDateTime(values[0]); if (ld < date && ld > lastDate) { lastDate = ld; lastE = currentE; } if (ld >= date && ld < nextDate) { nextDate = ld; nextE = currentE; } currentE++; } //SET ECLIPSE DATA if (lastE >= 0) { c.LunarEclipse.LastEclipse = new LunarEclipseDetails(se[lastE]); } if (nextE >= 0) { c.LunarEclipse.NextEclipse = new LunarEclipseDetails(se[nextE]); } }
/// <summary> /// Converts all Celestial values to local time. /// </summary> /// <param name="coord">Coordinate</param> /// <param name="offset">UTC offset</param> /// <returns>Celestial</returns> /// <example> /// The following example demonstrates how to get Celestial values in Local time. /// DateTime offsets are done manually for readability purposes of this example. /// <code> /// //Local time /// DateTime d = new DateTime(2018, 3, 19, 6, 56, 0, 0, DateTimeKind.Local); /// /// //EST Time is -4 hours from UTC /// double offset = -4; /// /// //Convert the date to UTC time /// d = d.AddHours(offset*-1); /// /// //Create a Coordinate with the UTC time /// Coordinate c = new Coordinate(39.0000, -72.0000, d); /// //Create a new Celestial object by converting the existing one to Local /// Celestial celestial = Celestial.Celestial_LocalTime(c, offset); /// /// Console.WriteLine(celestial.IsSunUp); //True /// Console.WriteLine(celestial.SunRise); //3/19/2018 6:54:25 AM /// </code> /// </example> public static Celestial Celestial_LocalTime(Coordinate coord, double offset) { if (offset < -12 || offset > 12) { throw new ArgumentOutOfRangeException("Time offsets cannot be greater 12 or less than -12."); } //Probably need to offset initial UTC date so user can op in local //Determine best way to do this. DateTime d = coord.GeoDate.AddHours(offset); //Get 3 objects for comparison Celestial cel = new Celestial(coord.Latitude.ToDouble(), coord.Longitude.ToDouble(), coord.GeoDate); Celestial celPre = new Celestial(coord.Latitude.ToDouble(), coord.Longitude.ToDouble(), coord.GeoDate.AddDays(-1)); Celestial celPost = new Celestial(coord.Latitude.ToDouble(), coord.Longitude.ToDouble(), coord.GeoDate.AddDays(1)); //Slip objects for comparison. Compare with slipped date. celPre.Local_Convert(coord, offset, Celestial_EagerLoad.All); cel.Local_Convert(coord, offset, Celestial_EagerLoad.All); celPost.Local_Convert(coord, offset, Celestial_EagerLoad.All); //Get SunSet int i = Determine_Slipped_Event_Index(cel.SunSet, celPre.SunSet, celPost.SunSet, d); cel.sunSet = Get_Correct_Slipped_Date(cel.SunSet, celPre.SunSet, celPost.SunSet, i); cel.AdditionalSolarTimes.civilDusk = Get_Correct_Slipped_Date(cel.AdditionalSolarTimes.CivilDusk, celPre.AdditionalSolarTimes.CivilDusk, celPost.AdditionalSolarTimes.CivilDusk, i); cel.AdditionalSolarTimes.nauticalDusk = Get_Correct_Slipped_Date(cel.AdditionalSolarTimes.NauticalDusk, celPre.AdditionalSolarTimes.NauticalDusk, celPost.AdditionalSolarTimes.NauticalDusk, i); //Get SunRise i = Determine_Slipped_Event_Index(cel.SunRise, celPre.SunRise, celPost.SunRise, d); cel.sunRise = Get_Correct_Slipped_Date(cel.SunRise, celPre.SunRise, celPost.SunRise, i); cel.AdditionalSolarTimes.civilDawn = Get_Correct_Slipped_Date(cel.AdditionalSolarTimes.CivilDawn, celPre.AdditionalSolarTimes.CivilDawn, celPost.AdditionalSolarTimes.CivilDawn, i); cel.AdditionalSolarTimes.nauticalDawn = Get_Correct_Slipped_Date(cel.AdditionalSolarTimes.NauticalDawn, celPre.AdditionalSolarTimes.NauticalDawn, celPost.AdditionalSolarTimes.NauticalDawn, i); //MoonRise i = Determine_Slipped_Event_Index(cel.MoonRise, celPre.MoonRise, celPost.MoonRise, d); cel.moonRise = Get_Correct_Slipped_Date(cel.MoonRise, celPre.MoonRise, celPost.MoonRise, i); //MoonSet i = Determine_Slipped_Event_Index(cel.MoonSet, celPre.MoonSet, celPost.MoonSet, d); cel.moonSet = Get_Correct_Slipped_Date(cel.MoonSet, celPre.MoonSet, celPost.MoonSet, i); //Local Conditions CelestialStatus[] cels = new CelestialStatus[] { celPre.MoonCondition, cel.MoonCondition, celPost.MoonCondition }; cel.moonCondition = GetStatus(cel.MoonRise, cel.MoonSet, cels); cels = new CelestialStatus[] { celPre.SunCondition, cel.SunCondition, celPost.SunCondition }; cel.sunCondition = GetStatus(cel.SunRise, cel.SunSet, cels); //Load IsUp values based on local time with populated Celestial //If EagerLoading Extensions used, this function will handle null values Calculate_Celestial_IsUp_Booleans(d, cel); return(cel); }
public static void GetMoonTimes(DateTime date, double lat, double lng, Celestial c) { c.MoonRise = null; c.MoonSet = null; DateTime t = new DateTime(date.Year, date.Month, date.Day, 0, 0, 0, DateTimeKind.Utc); c.MoonSet = null; c.MoonSet = null; double hc = 0.133 * rad, h0 = GetMoonPosition(t, lat, lng).Altitude - hc, h1, h2, a, b, xe, ye, d, roots, dx; double?x1 = null, x2 = null, rise = null, set = null; bool isRise = false; bool isSet = false; bool isNeg; if (h0 < 0) { isNeg = true; } else { isNeg = false; } // go in 2-hour chunks, each time seeing if a 3-point quadratic curve crosses zero (which means rise or set) for (var i = 1; i <= 24; i += 2) { h1 = GetMoonPosition(hoursLater(t, i), lat, lng).Altitude - hc; h2 = GetMoonPosition(hoursLater(t, i + 1), lat, lng).Altitude - hc; if (isNeg && h1 >= 0 || isNeg && h2 >= 0) { isNeg = false; isRise = true; } if (!isNeg && h1 < 0 || !isNeg && h2 < 0) { isNeg = true; isSet = true; } a = (h0 + h2) / 2 - h1; b = (h2 - h0) / 2; xe = -b / (2 * a); ye = (a * xe + b) * xe + h1; d = b * b - 4 * a * h1; roots = 0; if (d >= 0) { dx = Math.Sqrt(d) / (Math.Abs(a) * 2); x1 = xe - dx; x2 = xe + dx; if (Math.Abs(x1.Value) <= 1) { roots++; } if (Math.Abs(x2.Value) <= 1) { roots++; } if (x1 < -1) { x1 = x2; } } if (roots == 1) { if (h0 < 0) { rise = i + x1; } else { set = i + x1; } } else if (roots == 2) { rise = i + (ye < 0 ? x2 : x1); set = i + (ye < 0 ? x1 : x2); } if (rise != null && set != null) { break; } h0 = h2; } if (rise != null) { c.MoonRise = hoursLater(t, rise.Value); } if (set != null) { c.MoonSet = hoursLater(t, set.Value); } if (isRise && isSet) { c.MoonCondition = CelestialStatus.RiseAndSet; } else { if (!isRise && !isSet) { if (h0 >= 0) { c.MoonCondition = CelestialStatus.UpAllDay; } else { c.MoonCondition = CelestialStatus.DownAllDay; } } if (!isRise && isSet) { c.MoonCondition = CelestialStatus.NoRise; } if (isRise && !isSet) { c.MoonCondition = CelestialStatus.NoSet; } } }
public static void GetMoonSign(DateTime date, Celestial c) { //Formulas taken from https://www.astrocal.co.uk/moon-sign-calculator/ double d = date.Day; double m = date.Month; double y = date.Year; double hr = date.Hour; double mi = date.Minute; double f = hr + (mi / 60); double im = 12 * (y + 4800) + m - 3; double j = (2 * (im - Math.Floor(im / 12) * 12) + 7 + 365 * im) / 12; j = Math.Floor(j) + d + Math.Floor(im / 48) - 32083; double jd = j + Math.Floor(im / 4800) - Math.Floor(im / 1200) + 38; double T = ((jd - 2415020) + f / 24 - .5) / 36525; double ob = FNr(23.452294 - .0130125 * T); double ll = 973563 + 1732564379 * T - 4 * T * T; double g = 1012395 + 6189 * T; double n = 933060 - 6962911 * T + 7.5 * T * T; double g1 = 1203586 + 14648523 * T - 37 * T * T; d = 1262655 + 1602961611 * T - 5 * T * T; double M = 3600; double l = (ll - g1) / M; double l1 = ((ll - d) - g) / M; f = (ll - n) / M; d = d / M; y = 2 * d; double ml = 22639.6 * FNs(l) - 4586.4 * FNs(l - y); ml = ml + 2369.9 * FNs(y) + 769 * FNs(2 * l) - 669 * FNs(l1); ml = ml - 411.6 * FNs(2 * f) - 212 * FNs(2 * l - y); ml = ml - 206 * FNs(l + l1 - y) + 192 * FNs(l + y); ml = ml - 165 * FNs(l1 - y) + 148 * FNs(l - l1) - 125 * FNs(d); ml = ml - 110 * FNs(l + l1) - 55 * FNs(2 * f - y); ml = ml - 45 * FNs(l + 2 * f) + 40 * FNs(l - 2 * f); double tn = n + 5392 * FNs(2 * f - y) - 541 * FNs(l1) - 442 * FNs(y); tn = tn + 423 * FNs(2 * f) - 291 * FNs(2 * l - 2 * f); g = FNu(FNp(ll + ml)); double sign = Math.Floor(g / 30); double degree = (g - (sign * 30)); sign = sign + 1; switch (sign.ToString()) { case "1": c.AstrologicalSigns.MoonSign = "Aries"; break; case "2": c.AstrologicalSigns.MoonSign = "Taurus"; break; case "3": c.AstrologicalSigns.MoonSign = "Gemini"; break; case "4": c.AstrologicalSigns.MoonSign = "Cancer"; break; case "5": c.AstrologicalSigns.MoonSign = "Leo"; break; case "6": c.AstrologicalSigns.MoonSign = "Virgo"; break; case "7": c.AstrologicalSigns.MoonSign = "Libra"; break; case "8": c.AstrologicalSigns.MoonSign = "Scorpio"; break; case "9": c.AstrologicalSigns.MoonSign = "Sagitarius"; break; case "10": c.AstrologicalSigns.MoonSign = "Capricorn"; break; case "11": c.AstrologicalSigns.MoonSign = "Aquarius"; break; case "12": c.AstrologicalSigns.MoonSign = "Pisces"; break; default: c.AstrologicalSigns.MoonSign = "Pisces"; break; } }
/// <summary> /// Gets times for additional solar times /// </summary> private static void CalculateSunAngle(DateTime date, double longi, double lat, Celestial c) { //C# version of JavaScript date.valueOf(); TimeSpan ts = date - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); double dms = (ts.TotalMilliseconds / dayMS - .5 + j1970) - j2000; double lw = rad * -longi; double phi = rad * lat; double e = rad * 23.4397; double[] sc = sunCoords(dms); double H = SideRealTime(dms, lw) - sc[1]; // Console.WriteLine("Solar1: " + H); c.SunAzimuth = Math.Atan2(Math.Sin(H), Math.Cos(H) * Math.Sin(phi) - Math.Tan(sc[0]) * Math.Cos(phi)) * 180 / Math.PI + 180; c.SunAltitude = Math.Asin(Math.Sin(phi) * Math.Sin(sc[0]) + Math.Cos(phi) * Math.Cos(sc[0]) * Math.Cos(H)) * 180 / Math.PI; //Console.WriteLine(c.SunAltitude + " " + c.SunAzimuth); //double JD = JulianConversions.GetJulian(date); //Console.WriteLine("JD2: " + JD); //H = rad * MeeusFormulas.Get_Sidereal_Time(JD)-lw - sc[1]; //Console.WriteLine("Solar2: " + H); //c.SunAzimuth = Math.Atan2(Math.Sin(H), Math.Cos(H) * Math.Sin(phi) - Math.Tan(sc[0]) * Math.Cos(phi)) * 180 / Math.PI + 180; //c.SunAltitude = Math.Asin(Math.Sin(phi) * Math.Sin(sc[0]) + Math.Cos(phi) * Math.Cos(sc[0]) * Math.Cos(H)) * 180 / Math.PI; //Console.WriteLine(c.SunAltitude + " " + c.SunAzimuth); }
public static void CalculateSunTime(double lat, double longi, DateTime date, Celestial c, double offset = 0) { if (date.Year == 0001) { return; } //Return if date vaue hasn't been established. DateTime actualDate = new DateTime(date.Year, date.Month, date.Day, 0, 0, 0, DateTimeKind.Utc); ////Sun Time Calculations //Get Julian double lw = rad * -longi; double phi = rad * lat; //Rise Set DateTime?[] evDate = Get_Event_Time(lw, phi, -.8333, actualDate); c.SunRise = evDate[0]; c.SunSet = evDate[1]; c.SunCondition = CelestialStatus.RiseAndSet; //Azimuth and Altitude CalculateSunAngle(date, longi, lat, c); // neither sunrise nor sunset if ((!c.SunRise.HasValue) && (!c.SunSet.HasValue)) { if (c.SunAltitude < 0) { c.SunCondition = CelestialStatus.DownAllDay; } else { c.SunCondition = CelestialStatus.UpAllDay; } } // sunrise or sunset else { if (!c.SunRise.HasValue) { // No sunrise this date c.SunCondition = CelestialStatus.NoRise; } else if (!c.SunSet.HasValue) { // No sunset this date c.SunCondition = CelestialStatus.NoSet; } } //Additional Times c.AdditionalSolarTimes = new AdditionalSolarTimes(); //Dusk and Dawn //Civil evDate = Get_Event_Time(lw, phi, -6, actualDate); c.AdditionalSolarTimes.CivilDawn = evDate[0]; c.AdditionalSolarTimes.CivilDusk = evDate[1]; //Nautical evDate = Get_Event_Time(lw, phi, -12, actualDate); c.AdditionalSolarTimes.NauticalDawn = evDate[0]; c.AdditionalSolarTimes.NauticalDusk = evDate[1]; //Astronomical evDate = Get_Event_Time(lw, phi, -18, actualDate); c.AdditionalSolarTimes.AstronomicalDawn = evDate[0]; c.AdditionalSolarTimes.AstronomicalDusk = evDate[1]; //BottomDisc evDate = Get_Event_Time(lw, phi, -.2998, actualDate); c.AdditionalSolarTimes.SunriseBottomDisc = evDate[0]; c.AdditionalSolarTimes.SunsetBottomDisc = evDate[1]; CalculateSolarEclipse(date, lat, longi, c); }
public static void GetMoonIllumination(DateTime date, Celestial c, double lat, double lng) { date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, DateTimeKind.Utc); double d = toDays(date); CelCoords s = GetSunCoords(d); CelCoords m = GetMoonCoords(d, c); double sdist = 149598000, phi = Math.Acos(Math.Sin(s.dec) * Math.Sin(m.dec) + Math.Cos(s.dec) * Math.Cos(m.dec) * Math.Cos(s.ra - m.ra)), inc = Math.Atan2(sdist * Math.Sin(phi), m.dist - sdist * Math.Cos(phi)), angle = Math.Atan2(Math.Cos(s.dec) * Math.Sin(s.ra - m.ra), Math.Sin(s.dec) * Math.Cos(m.dec) - Math.Cos(s.dec) * Math.Sin(m.dec) * Math.Cos(s.ra - m.ra)); MoonIllum mi = new MoonIllum(); mi.Fraction = (1 + Math.Cos(inc)) / 2; mi.Phase = 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI; mi.Angle = angle; c.MoonIllum = mi; string moonName = ""; int moonDate = 0; //GET PHASE NAME //CHECK MOON AT BEGINNING AT END OF DAY TO GET DAY PHASE IN UTC DateTime dMon = new DateTime(date.Year, date.Month, 1); for (int x = 1; x <= date.Day; x++) { DateTime nDate = new DateTime(dMon.Year, dMon.Month, x, 0, 0, 0, DateTimeKind.Utc); d = toDays(nDate); s = GetSunCoords(d); m = GetMoonCoords(d, c); phi = Math.Acos(Math.Sin(s.dec) * Math.Sin(m.dec) + Math.Cos(s.dec) * Math.Cos(m.dec) * Math.Cos(s.ra - m.ra)); inc = Math.Atan2(sdist * Math.Sin(phi), m.dist - sdist * Math.Cos(phi)); angle = Math.Atan2(Math.Cos(s.dec) * Math.Sin(s.ra - m.ra), Math.Sin(s.dec) * Math.Cos(m.dec) - Math.Cos(s.dec) * Math.Sin(m.dec) * Math.Cos(s.ra - m.ra)); double startPhase = 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI; nDate = new DateTime(dMon.Year, dMon.Month, x, 23, 59, 59, DateTimeKind.Utc); d = toDays(nDate); s = GetSunCoords(d); m = GetMoonCoords(d, c); phi = Math.Acos(Math.Sin(s.dec) * Math.Sin(m.dec) + Math.Cos(s.dec) * Math.Cos(m.dec) * Math.Cos(s.ra - m.ra)); inc = Math.Atan2(sdist * Math.Sin(phi), m.dist - sdist * Math.Cos(phi)); angle = Math.Atan2(Math.Cos(s.dec) * Math.Sin(s.ra - m.ra), Math.Sin(s.dec) * Math.Cos(m.dec) - Math.Cos(s.dec) * Math.Sin(m.dec) * Math.Cos(s.ra - m.ra)); double endPhase = 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI; //Determine Moon Name. if (startPhase <= .5 && endPhase >= .5) { moonDate = x; moonName = GetMoonName(dMon.Month, moonName); } //Get Moon Name (month, string); //Get Moon Phase Name if (date.Day == x) { if (startPhase > endPhase) { mi.PhaseName = "New Moon"; break; } if (startPhase <= .25 && endPhase >= .25) { mi.PhaseName = "First Quarter"; break; } if (startPhase <= .5 && endPhase >= .5) { mi.PhaseName = "Full Moon"; break; } if (startPhase <= .75 && endPhase >= .75) { mi.PhaseName = "Last Quarter"; break; } if (startPhase > 0 && startPhase < .25 && endPhase > 0 && endPhase < .25) { mi.PhaseName = "Waxing Crescent"; break; } if (startPhase > .25 && startPhase < .5 && endPhase > .25 && endPhase < .5) { mi.PhaseName = "Waxing Gibbous"; break; } if (startPhase > .5 && startPhase < .75 && endPhase > .5 && endPhase < .75) { mi.PhaseName = "Waning Gibbous"; break; } if (startPhase > .75 && startPhase < 1 && endPhase > .75 && endPhase < 1) { mi.PhaseName = "Waning Crescent"; break; } } } if (date.Day == moonDate) { c.AstrologicalSigns.MoonName = moonName; } else { c.AstrologicalSigns.MoonName = ""; } CalculateLunarEclipse(date, lat, lng, c); }