/// <summary> /// Calculates sun times for a given date, latitude/longitude, and, optionally, /// the observer height (in meters) relative to the horizon /// </summary> /// <param name="date">date to calculate for</param> /// <param name="latitude">latitude in degrees</param> /// <param name="longitude">longitude in degrees</param> /// <param name="height">observer height relative to the horizon in metres (optional)</param> /// <returns></returns> public static SunTimes GetTimes(DateTime date, double latitude, double longitude, double height = 0) { var lw = Constants.Rad * -longitude; var phi = Constants.Rad * latitude; var dh = Sun.ObserverAngle(height); var d = Calendar.ToDays(date); var n = Sun.JulianCycle(d, lw); var ds = Sun.ApproxTransit(0, lw, n); var M = Sun.SolarMeanAnomaly(ds); var L = Sun.EclipticLongitude(M); var dec = Position.Declination(L, 0); var Jnoon = Sun.SolarTransitJ(ds, M, L); var result = new SunTimes { SolarNoon = Calendar.FromJulian(Jnoon), Nadir = Calendar.FromJulian(Jnoon - 0.5) }; for (int i = 0, len = Times.Count; i < len; i += 1) { var time = Times[i]; var h0 = (time.Angle + dh) * Constants.Rad; var Jset = Sun.GetSetJ(h0, lw, phi, dec, n, M, L); if (!double.IsNaN(Jset)) { var Jrise = Jnoon - (Jset - Jnoon); time.SetRiseProperty(result, Calendar.FromJulian(Jrise)); time.SetSetProperty(result, Calendar.FromJulian(Jset)); } } return(result); }