diff --git a/CoordinateSharp.Magnetic/CoordinateSharp.Magnetic.csproj b/CoordinateSharp.Magnetic/CoordinateSharp.Magnetic.csproj
index 891084a7..af728234 100644
--- a/CoordinateSharp.Magnetic/CoordinateSharp.Magnetic.csproj
+++ b/CoordinateSharp.Magnetic/CoordinateSharp.Magnetic.csproj
@@ -47,7 +47,7 @@ For more information, please contact Signature Group, LLC at this address: sales
net40; netstandard1.3; netstandard1.4; netstandard2.0; netstandard2.1; net50; net60; net70
true
true
- 1.1.8.0
+ 1.1.9.0
Signature Group, LLC
https://github.com/Tronald/CoordinateSharp
@@ -61,7 +61,7 @@ For more information, please contact Signature Group, LLC at this address: sales
CoordinateSharp.Magnetic
CoordinateSharp.Magnetic
- 1.1.7.0
+ 1.1.9.0
true
true
128x128.png
diff --git a/CoordinateSharp/Celestial/Celestial.Coordinates.cs b/CoordinateSharp/Celestial/Celestial.Coordinates.cs
index 0b9a8b86..ce265a4c 100644
--- a/CoordinateSharp/Celestial/Celestial.Coordinates.cs
+++ b/CoordinateSharp/Celestial/Celestial.Coordinates.cs
@@ -54,6 +54,7 @@ namespace CoordinateSharp
public class SolarCoordinates
{
//Test Against https://www.timeanddate.com/worldclock/sunearth.html
+
internal double trueLongitude;
internal double trueLatitude;
internal double julianDayDecimal;
@@ -64,7 +65,7 @@ public class SolarCoordinates
internal double rightAscension;
internal double declination;
internal double geometricMeanLongitude;
-
+ internal double obliquityOfEcliptic;
///
/// Radius Vector (expressed in astronomical units).
@@ -96,6 +97,11 @@ public class SolarCoordinates
///
public double GeometricMeanLongitude { get { return geometricMeanLongitude; } }
+ ///
+ /// Obliquity of the Ecliptic
+ ///
+ public double ObliquityOfEcliptic { get { return obliquityOfEcliptic; } }
+
///
/// Subsolar Latitude. The point at which the sun is perceived to be directly overhead of the Earth (at the zenith).
///
diff --git a/CoordinateSharp/Celestial/Solar/SunCalculations.cs b/CoordinateSharp/Celestial/Solar/SunCalculations.cs
index 40e29e2b..7e8cca02 100644
--- a/CoordinateSharp/Celestial/Solar/SunCalculations.cs
+++ b/CoordinateSharp/Celestial/Solar/SunCalculations.cs
@@ -433,7 +433,7 @@ public static SolarCoordinates Get_Solar_Coordinates(DateTime d, double offset)
double tdec = Math.Asin(Math.Sin(E.ToRadians()) * Math.Sin(trueLongitude.ToRadians())); //25.7 True declination. Asin used in liu of sin.
- double CE = E + .00256 * Math.Cos(ascendingNode.ToRadians());//22.2 Obliquity of the ecliptic
+ double CE = E + .00256 * Math.Cos(ascendingNode.ToRadians());//25.6 & 25.7 Apparent position of the sun.
double ara = Math.Atan2(Math.Cos(CE.ToRadians()) * Math.Sin(apparentLongitude.ToRadians()), Math.Cos(apparentLongitude.ToRadians())); //25.8 Apparent Right Ascensions. Using Atan2 we can move tan to the right side of the function with Numerator, Denominator
double adec = Math.Asin(Math.Sin(CE.ToRadians()) * Math.Sin(apparentLongitude.ToRadians())); //25.8 Apparent declination. Asin used in liu of sin.
@@ -443,6 +443,7 @@ public static SolarCoordinates Get_Solar_Coordinates(DateTime d, double offset)
//Set to degrees
//celC.trueRightAscension = tra.ToDegrees();
//celC.trueDeclination = tdec.ToDegrees();
+ var tr = tra.ToDegrees().NormalizeDegrees360();
celC.rightAscension = ara.ToDegrees().NormalizeDegrees360();
celC.declination = adec.ToDegrees();
celC.julianDayDecimal = JD-.5 - Math.Floor(JD-.5);
@@ -450,7 +451,8 @@ public static SolarCoordinates Get_Solar_Coordinates(DateTime d, double offset)
celC.longitude = apparentLongitude.NormalizeDegrees360();
celC.radiusVector = R;
celC.geometricMeanLongitude = L0.NormalizeDegrees360();
- //Latitude is always 0 for sun as perturbations no accounted for in low accuracy formulas
+ celC.obliquityOfEcliptic = E.NormalizeDegrees360();
+ //Latitude is always 0 for sun as perturbations not accounted for in low accuracy formulas
celC.latitude = 0;
celC.trueLatitude = 0;
diff --git a/CoordinateSharp/CoordinateSharp.csproj b/CoordinateSharp/CoordinateSharp.csproj
index d5629e12..02216362 100644
--- a/CoordinateSharp/CoordinateSharp.csproj
+++ b/CoordinateSharp/CoordinateSharp.csproj
@@ -50,29 +50,27 @@ Please visit http://coordinatesharp.com/licensing or contact Signature Group, LL
net40; netstandard1.3; netstandard1.4; netstandard2.0; netstandard2.1; net50; net60; net70
true
true
- 2.18.1.1
+ 2.19.1.1
Signature Group, LLC
https://github.com/Tronald/CoordinateSharp
Copyright 2023
CoordinateSharp is a high powered, lightweight .NET library that can convert geographical coordinates, perform distance logic, and calculate location based sun, moon, and magnetic information with minimal code.
- -Improves UTM and MGRS conversion efficiency by 13x.
--Adds ability create geofence from a specified GEOREF coordinate and precision level.
--Adds ability to locate GEOREF box corners based on a given precision level.
--Restricts GEOREF easting and northing minutes and seconds to 59.999... to comply with library standards.
+ -Fixes "Leap Year Bug" impacting celestial calculations and Julian date conversions prior to 1582 (pre-Gregorian).
+-Exposes the Obliquity of Ecliptic value within the SolarCoordinate class.
Conversion; Latitude; Longitude; Coordinates; Geography; Sun; Moon; Solar; Lunar; Time; MGRS; UTM; EPSG:3857; ECEF; GEOREF; Web Mercator;
License.txt
CoordinateSharp
CoordinateSharp
- 2.17.1.1
+ 2.19.1.1
true
true
128x128.png
CoordinateSharp Strong Name.snk
false
- 2.17.1.1
+ 2.19.1.1
https://github.com/Tronald/CoordinateSharp
README.md
snupkg
diff --git a/CoordinateSharp/Julian/Julian.cs b/CoordinateSharp/Julian/Julian.cs
index 8e6c8b3d..71d35b43 100644
--- a/CoordinateSharp/Julian/Julian.cs
+++ b/CoordinateSharp/Julian/Julian.cs
@@ -43,6 +43,8 @@ or shipping CoordinateSharp with a closed source product.
Please visit http://coordinatesharp.com/licensing or contact Signature Group, LLC to purchase a commercial license, or for any questions regarding the AGPL 3.0 license requirements or free use license: sales@signatgroup.com.
*/
using System;
+using System.Diagnostics;
+
namespace CoordinateSharp
{
///
@@ -125,6 +127,10 @@ public static double GetJulian_Epoch1970(DateTime d)
/// Returns date from Julian
/// Meeus ch. 7
///
+ ///
+ /// The Gregorian calendar (started in 1582) contains different leap year rules than the Julian calendar. To avoid exceptions, any invalid pre-1582 Gregorian leap year conversions of
+ /// February 29th will shift to March 1st. As such you may see two consecutive Julian to Gregorian conversions produce a date of March 1st on rare occasions.
+ ///
/// Julian date
/// DateTime
///
@@ -136,7 +142,7 @@ public static double GetJulian_Epoch1970(DateTime d)
///
public static DateTime? GetDate_FromJulian(double j)
{
- if (Double.IsNaN(j)) { return null; } //No Event Occured
+ if (Double.IsNaN(j)) { return null; } //No Event Occurred
j = j + .5;
double Z = Math.Floor(j);
@@ -176,6 +182,19 @@ public static double GetJulian_Epoch1970(DateTime d)
hours = Math.Floor(hours);
minutes = Math.Floor(minutes);
+ //Leap year safety check due to differences in Julian and Gregorian calendars.
+ //This limitation of CoordinateSharp is documented. Safety check implemented to prevent breakage.
+ if (month == 2 && day == 29)
+ {
+ if (year / 100 == (int)(year / 100) && year / 400 != (int)(year / 400))
+ {
+ Debug.WriteLine($"CAUTION: Julian date {j} does not exist on the Gregorian calendar (29-FEB-{year}). Shifting to next Gregorian day (1-MAR-{year}).");
+ month++;
+ day = 1;
+
+ }
+ }
+
DateTime? date = new DateTime?(new DateTime((int)year, (int)month, (int)day, (int)hours, (int)minutes, (int)seconds));
return date;
}
@@ -183,6 +202,10 @@ public static double GetJulian_Epoch1970(DateTime d)
/// Returns date from Julian based on epoch 2000
/// Meeus ch. 7
///
+ ///
+ /// The Gregorian calendar (started in 1582) contains different leap year rules than the Julian calendar. To avoid exceptions, any invalid pre-1582 Gregorian leap year conversions of
+ /// February 29th will shift to March 1st. As such you may see two consecutive Julian to Gregorian conversions produce a date of March 1st on rare occasions.
+ ///
/// Julian date (epoch 2000)
/// DateTime
///
@@ -200,6 +223,10 @@ public static double GetJulian_Epoch1970(DateTime d)
/// Returns date from Julian based on epoch 1970
/// Meeus ch. 7
///
+ ///
+ /// The Gregorian calendar (started in 1582) contains different leap year rules than the Julian calendar. To avoid exceptions, any invalid pre-1582 Gregorian leap year conversions of
+ /// February 29th will shift to March 1st. As such you may see two consecutive Julian to Gregorian conversions produce a date of March 1st on rare occasions.
+ ///
/// Julian date (epoch 1970)
/// DateTime
///
diff --git a/CoordinateSharp_UnitTests/Formatters.cs b/CoordinateSharp_UnitTests/Formatters.cs
index 9a057971..257a2aa9 100644
--- a/CoordinateSharp_UnitTests/Formatters.cs
+++ b/CoordinateSharp_UnitTests/Formatters.cs
@@ -6,6 +6,8 @@
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
+using NuGet.Frameworks;
+
namespace CoordinateSharp_UnitTests
{
[TestClass]
@@ -116,6 +118,24 @@ public void Normalize360()
Assert.AreEqual(201.80720, Format.NormalizeDegrees360(signed),.000000001);
}
+ [TestMethod]
+ public void JulianLeapYearSafetyCheck()
+ {
+ //Ensure no throws due to calendar differences
+ JulianConversions.GetDate_FromJulian(1757641.5);
+
+ for (int x = 100; x < 2400; x += 100)
+ {
+ Celestial.CalculateCelestialTimes(39, -72, new DateTime(x, 2, 26));
+ Celestial.CalculateCelestialTimes(39, -72, new DateTime(x, 4, 21, 10, 10, 12));
+ }
+
+
+
+ }
+
+
+
///
/// Ensures Coordinate and serialize in binary and deserialze properly
///