Instantly share code, notes, and snippets.

Tafkas/computeSunrise.js

Last active August 3, 2023 20:04
Show Gist options
• 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; }

luckylooke commented May 5, 2017 • edited

@drewreece nicer implementation:

``````function dayOfYear() {
var now = new Date();
var start = new Date(now.getFullYear(), 0, 0);
var diff = now - start;
var oneDay = 1000 * 60 * 60 * 24;
return Math.floor(diff / oneDay);
}
``````

luckylooke commented May 5, 2017 • edited

If somebody wants to convert return values to date objects, like this: `new Date( computeSunrise() )` You need to do following:
Remove these piece of code:

`````` //convert UT value to local time zone of latitude/longitude
localT = UT + 1;
``````

And replace return statement by this:

``````//convert to Milliseconds
var now = new Date();
return new Date( now.getFullYear(), now.getMonth(), now.getDate() ).getTime() + ( UT * 3600 * 1000 );
``````

fixed results..
Thanks for sharing the code ;)

LouisHeche commented Jul 26, 2018

Hello,

Does anybody understand this line of the algorithm

``````//calculate local mean time of rising/setting
T = H + RA - (0.06571 * t) - 6.622;
``````

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