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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

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
You can’t perform that action at this time.