|
|
|
@ -78,35 +78,35 @@ public struct Solar {
|
|
|
|
|
let lngHour = coordinate.longitude / 15 |
|
|
|
|
|
|
|
|
|
let hourTime: Double = sunriseSunset == .sunrise ? 6 : 18 |
|
|
|
|
let t = day + ((hourTime - lngHour) / 24) |
|
|
|
|
let time = day + ((hourTime - lngHour) / 24) |
|
|
|
|
|
|
|
|
|
// Calculate the suns mean anomaly |
|
|
|
|
let M = (0.9856 * t) - 3.289 |
|
|
|
|
let meanAnomaly = (0.9856 * time) - 3.289 |
|
|
|
|
|
|
|
|
|
// Calculate the sun's true longitude |
|
|
|
|
let subexpression1 = 1.916 * sin(M.degreesToRadians) |
|
|
|
|
let subexpression2 = 0.020 * sin(2 * M.degreesToRadians) |
|
|
|
|
var L = M + subexpression1 + subexpression2 + 282.634 |
|
|
|
|
let subexpression1 = 1.916 * sin(meanAnomaly.degreesToRadians) |
|
|
|
|
let subexpression2 = 0.020 * sin(2 * meanAnomaly.degreesToRadians) |
|
|
|
|
var longitude = meanAnomaly + subexpression1 + subexpression2 + 282.634 |
|
|
|
|
|
|
|
|
|
// Normalise L into [0, 360] range |
|
|
|
|
L = normalise(L, withMaximum: 360) |
|
|
|
|
longitude = normalise(longitude, withMaximum: 360) |
|
|
|
|
|
|
|
|
|
// Calculate the Sun's right ascension |
|
|
|
|
var RA = atan(0.91764 * tan(L.degreesToRadians)).radiansToDegrees |
|
|
|
|
var rightAscenscion = atan(0.91764 * tan(longitude.degreesToRadians)).radiansToDegrees |
|
|
|
|
|
|
|
|
|
// Normalise RA into [0, 360] range |
|
|
|
|
RA = normalise(RA, withMaximum: 360) |
|
|
|
|
rightAscenscion = normalise(rightAscenscion, withMaximum: 360) |
|
|
|
|
|
|
|
|
|
// Right ascension value needs to be in the same quadrant as L... |
|
|
|
|
let Lquadrant = floor(L / 90) * 90 |
|
|
|
|
let RAquadrant = floor(RA / 90) * 90 |
|
|
|
|
RA = RA + (Lquadrant - RAquadrant) |
|
|
|
|
let Lquadrant = floor(longitude / 90) * 90 |
|
|
|
|
let RAquadrant = floor(rightAscenscion / 90) * 90 |
|
|
|
|
rightAscenscion = rightAscenscion + (Lquadrant - RAquadrant) |
|
|
|
|
|
|
|
|
|
// Convert RA into hours |
|
|
|
|
RA = RA / 15 |
|
|
|
|
rightAscenscion = rightAscenscion / 15 |
|
|
|
|
|
|
|
|
|
// Calculate Sun's declination |
|
|
|
|
let sinDec = 0.39782 * sin(L.degreesToRadians) |
|
|
|
|
let sinDec = 0.39782 * sin(longitude.degreesToRadians) |
|
|
|
|
let cosDec = cos(asin(sinDec)) |
|
|
|
|
|
|
|
|
|
// Calculate the Sun's local hour angle |
|
|
|
@ -124,24 +124,24 @@ public struct Solar {
|
|
|
|
|
|
|
|
|
|
// Finish calculating H and convert into hours |
|
|
|
|
let tempH = sunriseSunset == .sunrise ? 360 - acos(cosH).radiansToDegrees : acos(cosH).radiansToDegrees |
|
|
|
|
let H = tempH / 15.0 |
|
|
|
|
let hours = tempH / 15.0 |
|
|
|
|
|
|
|
|
|
// Calculate local mean time of rising |
|
|
|
|
let T = H + RA - (0.06571 * t) - 6.622 |
|
|
|
|
let localMeanRisingTime = hours + rightAscenscion - (0.06571 * time) - 6.622 |
|
|
|
|
|
|
|
|
|
// Adjust time back to UTC |
|
|
|
|
var UT = T - lngHour |
|
|
|
|
var utcCompatibleTime = localMeanRisingTime - lngHour |
|
|
|
|
|
|
|
|
|
// Normalise UT into [0, 24] range |
|
|
|
|
UT = normalise(UT, withMaximum: 24) |
|
|
|
|
utcCompatibleTime = normalise(utcCompatibleTime, withMaximum: 24) |
|
|
|
|
|
|
|
|
|
// Calculate all of the sunrise's / sunset's date components |
|
|
|
|
let hour = floor(UT) |
|
|
|
|
let minute = floor((UT - hour) * 60.0) |
|
|
|
|
let second = (((UT - hour) * 60) - minute) * 60.0 |
|
|
|
|
let hour = floor(utcCompatibleTime) |
|
|
|
|
let minute = floor((utcCompatibleTime - hour) * 60.0) |
|
|
|
|
let second = (((utcCompatibleTime - hour) * 60) - minute) * 60.0 |
|
|
|
|
|
|
|
|
|
let shouldBeYesterday = lngHour > 0 && UT > 12 && sunriseSunset == .sunrise |
|
|
|
|
let shouldBeTomorrow = lngHour < 0 && UT < 12 && sunriseSunset == .sunset |
|
|
|
|
let shouldBeYesterday = lngHour > 0 && utcCompatibleTime > 12 && sunriseSunset == .sunrise |
|
|
|
|
let shouldBeTomorrow = lngHour < 0 && utcCompatibleTime < 12 && sunriseSunset == .sunset |
|
|
|
|
|
|
|
|
|
let setDate: Date |
|
|
|
|
if shouldBeYesterday { |
|
|
|
|