# Rise and Set Algorithm

 Julian Date: Lattitude: Longitude: Right Ascension: Declination:
 Output Rise: Transit: Set:

$$\cos H_0 = \dfrac{\sin h_0 - \sin \varphi \sin \delta }{\cos \varphi \cos \delta}$$

If $$\cos H_0$$ < -1 or > 1, the point is either always above or below the horizon.

$$transit = \dfrac{\delta + L - \Theta_0 }{360^{\circ}}$$

$$rise = transit - \dfrac{H_0}{360^{\circ}}$$

$$set = transit + \dfrac{H_0}{360^{\circ}}$$

$$\delta$$ Declination
$$L$$ Longitude
$$\varphi$$ Latitude
$$h_0$$ Apparent rise or set angle, -0.8333 for the Sun, +0.125 for the Moon, and -0.5667 for most other objects.
$$\Theta_0$$ Greenwich sidereal time at 0h for the day in question.

The output is adjusted for the current time zone, which may differ from the time zone in effect for a different date (e.g. Daylight Saving Time)

A simplified implementation of the Rise, Set, and Transit algorithm from the book Astronomical Algorithms by Jean Meeus. For objects whose position changes significantly over the course of they day (e.g. the Sun or Moon) it's more accurate to iteravley re-compute the object's position for each specific time for the event you're interested in. The Sun is considered to be set when the entire Sun is below the horizon, not the center of it like for other objects. Also atmospheric refraction causes the visual setting of an object to be later than the actual, geometric setting. Meeus' recommeneded values for h0 are included in the code to correct for these effects, here I have hard coded the value for the Sun.

One important note, is that Meeus considers Longitudes in the West to be positive, and East negative, which is the opposite of how pretty much everything else works. So, if you're using GPS coordinates, remember to negate the longitude.


//By Greg Miller gmiller@gregmiller.net www.astrogreg.com
//Released as public domain
const toDeg=180.0/Math.PI;

//Corrects values to make them between 0 and 1
function constrain(v){
if(v<0){return v+1;}
if(v>1){return v-1;}
return v;
}

//All angles must be in radians
//Outputs are times in hours GMT (not accounting for daylight saving time)
//From Meeus Page 101
function getRiseSet(jd,lat,lon,ra,dec){
const h0=-0.8333 //For Sun
//const h0=-0.5667 //For stars and planets
//const h0=0.125   //For Moon

const cosH=(Math.sin(h0*Math.PI/180.0)-Math.sin(lat)*Math.sin(dec)) / (Math.cos(lat)*Math.cos(dec));
const H0=Math.acos(cosH)*180.0/Math.PI;

const gmst=GMST(Math.floor(jd)+.5);

const transit=(ra*toDeg+lon*toDeg-gmst)/360.0;
const rise=transit-(H0/360.0);
const set=transit+(H0/360.0);

return [constrain(transit)*24.0,constrain(rise)*24.0,constrain(set)*24.0];
}

//Greenwhich mean sidreal time from Meeus page 87
//Input is julian date, does not have to be 0h
//Output is angle in degrees
function GMST(jd){
const T=(jd-2451545.0)/36525.0;
let st=280.46061837+360.98564736629*(jd-2451545.0)+0.000387933*T*T - T*T*T/38710000.0;
st=st%360;
if(st<0){st+=360;}

return st;
//return st*Math.PI/180.0;
}