Last active
August 1, 2024 20:48
-
-
Save Tafkas/4742250 to your computer and use it in GitHub Desktop.
A simple sunrise-sunset algorithm taken from http://williams.best.vwh.net/sunrise_sunset_algorithm.htm in JavaScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function computeSunrise(day, sunrise) { | |
/*Sunrise/Sunset Algorithm taken from | |
http://williams.best.vwh.net/sunrise_sunset_algorithm.htm | |
inputs: | |
day = day of the year | |
sunrise = true for sunrise, false for sunset | |
output: | |
time of sunrise/sunset in hours */ | |
//lat, lon for Berlin, Germany | |
var longitude = 13.408056; | |
var latitude = 52.518611; | |
var zenith = 90.83333333333333; | |
var D2R = Math.PI / 180; | |
var R2D = 180 / Math.PI; | |
// convert the longitude to hour value and calculate an approximate time | |
var lnHour = longitude / 15; | |
var t; | |
if (sunrise) { | |
t = day + ((6 - lnHour) / 24); | |
} else { | |
t = day + ((18 - lnHour) / 24); | |
}; | |
//calculate the Sun's mean anomaly | |
M = (0.9856 * t) - 3.289; | |
//calculate the Sun's true longitude | |
L = M + (1.916 * Math.sin(M * D2R)) + (0.020 * Math.sin(2 * M * D2R)) + 282.634; | |
if (L > 360) { | |
L = L - 360; | |
} else if (L < 0) { | |
L = L + 360; | |
}; | |
//calculate the Sun's right ascension | |
RA = R2D * Math.atan(0.91764 * Math.tan(L * D2R)); | |
if (RA > 360) { | |
RA = RA - 360; | |
} else if (RA < 0) { | |
RA = RA + 360; | |
}; | |
//right ascension value needs to be in the same qua | |
Lquadrant = (Math.floor(L / (90))) * 90; | |
RAquadrant = (Math.floor(RA / 90)) * 90; | |
RA = RA + (Lquadrant - RAquadrant); | |
//right ascension value needs to be converted into hours | |
RA = RA / 15; | |
//calculate the Sun's declination | |
sinDec = 0.39782 * Math.sin(L * D2R); | |
cosDec = Math.cos(Math.asin(sinDec)); | |
//calculate the Sun's local hour angle | |
cosH = (Math.cos(zenith * D2R) - (sinDec * Math.sin(latitude * D2R))) / (cosDec * Math.cos(latitude * D2R)); | |
var H; | |
if (sunrise) { | |
H = 360 - R2D * Math.acos(cosH) | |
} else { | |
H = R2D * Math.acos(cosH) | |
}; | |
H = H / 15; | |
//calculate local mean time of rising/setting | |
T = H + RA - (0.06571 * t) - 6.622; | |
//adjust back to UTC | |
UT = T - lnHour; | |
if (UT > 24) { | |
UT = UT - 24; | |
} else if (UT < 0) { | |
UT = UT + 24; | |
} | |
//convert UT value to local time zone of latitude/longitude | |
localT = UT + 1; | |
//convert to Milliseconds | |
return localT * 3600 * 1000; | |
} |
@Tafkas Would you mind putting this code under an open source license? MIT would be handy for me.
Your source link for the algorithm is dead, but can still be found at https://web.archive.org/web/20161022214335/http://williams.best.vwh.net/sunrise_sunset_algorithm.htm or the original print: https://books.google.de/books?id=GbDC6AaH-kAC&hl=de&pg=SL2-PA5
Not entirely sure how much copyright from the book remains in your code.
BTW you might also wanna replicate that the algorithm was meant to be used in 1950-2000, and between 65°N and 65°S :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello,
Does anybody understand this line of the algorithm
For me the local mean time should only be a addition of the Sun's local hour and the right ascension. I don't get how the time of the year comes in consideration and where does this constant 6.622 comes from. I found that the 0.06571 is equal to 365.25/24 but it doesn't help me much for my understanding