Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A simple sunrise-sunset algorithm taken from http://williams.best.vwh.net/sunrise_sunset_algorithm.htm in JavaScript
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;
}
@drewreece
Copy link

drewreece commented Mar 18, 2014

This needs the dayOfYear() function.

function dayOfYear() {
      var yearFirstDay = Math.floor(new Date().setFullYear(new Date().getFullYear(), 0, 1) / 86400000);
      var today = Math.ceil((new Date().getTime()) / 86400000);
      var dayOfYear = today - yearFirstDay;
      return dayOfYear;
  }

I took it from your site… http://thule.mine.nu/html/
Thanks :)

@jceaser
Copy link

jceaser commented Mar 24, 2014

Do you have a unit test? I wrote up the same code but I'm trying to verify that the numbers are correct.

@luckylooke
Copy link

luckylooke commented May 5, 2017

@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);
	}

from http://stackoverflow.com/a/8619946/861615

@luckylooke
Copy link

luckylooke commented May 5, 2017

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
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment