JavaScript Class for Sunrise and Sunset Calculations
A JavaScript class for calculating sunrise and sunset times based on latitude, longitude, and date.
FeedbackBy Preston Hunt, 23 January 2011

Background

I wanted to add a feature to Presto's Sidebar Clock that would automatically adjust the color of the clock based on the time of day. Because the clock has support for international time zones, I thought it might be helpful to know whether it was day or night in the other time zones that a user tracks.

There are a lot of web sites that calculate this information. And most of them use JavaScript. And some sites, such as NOAA, had a generous license that would allow reuse of the code. Unfortunately, extracting the code and making it usable proved more difficult than it should have been.

Eventually, I found a page with the calculations and decided it would be faster to go ahead and write it myself from the grounds up. I've generalized it a bit and made it a class in the hopes that other developers can use it.

Example

Here's how you use it:

var tokyo = new SunriseSunset( 2011, 1, 19, 35+40/60, 139+45/60); 
tokyo.sunriseUtcHours()      --> 21.8199 = 21:49 GMT
tokyo.sunsetUtcHours()       --> 7.9070  = 07:54 GMT
tokyo.sunriseLocalHours(9)   --> 6.8199  = 06:49 at GMT+9
tokyo.sunsunsetLocalHours(9) --> 16.9070 = 16:54 at GMT+9
tokyo.isDaylight(1.5)        --> true

Code

The code is available under an Apache 2.0 License on Pastebin.

Are you using my code in your project? Did you find a bug? Let me know!

blog comments powered by Disqus

Comments

From Ned Gulley on 2013-09-20T04:29:54Z:

I'm using it for my sunset clock here: http://www.starchamber.com/... (see also http://www.starchamber.com/...

From jamstooks on 2013-04-21T05:02:16Z:

Thanks, Preston. This is a great tool! Once I get my project into production, I'll share a link. In the meantime, I did create a JSFiddle to run some quick tests:

http://jsfiddle.net/jamstoo...

One thing I will probably do is, change this to accept different Zeniths as I plan to work with the nautical one. Also, there's a typo in the docs... tokyo.sunsunsetLocalHours(9) should be tokyo.sunsunsetLocalHours(9). Thanks again. Saved me having to implement this algorithm myself... and it wouldn't have been anywhere near as clean.

From presto8 on 2013-04-21T14:57:10Z:

Excellent! Glad to hear you find it useful and are building upon my work (and for sharing the JSFiddle link). Thanks for reporting the typo, I fixed it just now.

From Thomas on 2012-05-28T08:00:01Z:

I tried using this for a specified date, but I only get output for the system clock derived date. Here's my code:
    <script type="text/javascript">
        var dublin = new SunriseSunset( 2012, 1, 1, 53+20/60, -(6+15/60));
        document.write('<h1>Sunrise at ' + dublin.sunriseLocalHours(1) + '</h1>');
        document.write('<h1>Sunset at ' + dublin.sunsetLocalHours(1) + '</h1>');
    </script>
No matter what month/day values I plug in, this always generates for today's sunrise/set. If I change my system clock, the sunrise/set adjusts according to that time of year.
What am I doing wrong?

From Guest on 2011-03-24T06:01:49Z:

Heh. I'm a dork. I changed your code to force getting the latest date, and didn't even bother to use three of the variables I'd set in SunriseSunset. When I tested your code I used getYear() and getMonth(). This was a mistake since I should have used getFullYear(), and getMonth() + 1.

You're calculations are correct. Guess that's what I get coding until 3 in the morning.

From trev.norris on 2011-02-28T06:16:58Z:

For the love of everything holy, thank you for posting this. I've spent the last two days trying to reconstruct exactly what you've done here, with little success. I ran into the same problems you did, with unusually large and complicated libraries and lacking instructions.

From presto8 on 2011-03-02T16:23:15Z:

Awesome, this makes me very happy to know that somebody else is benefiting from my code! I just uploaded a slightly updated version to Pastebin which has improved test vectors. Come back and post a link to your project if you don't mind, I would love to see what you're developing.

From trevnorris on 2011-03-08T06:54:54Z:

I've uploaded a revised edition of your code to (http://pastebin.com/qCErN6w0). The function getDOY() was returning an incorrect value. Also added a few formatting changes to get the library under 2KB using the YUI compressor.

It's being used on my home page (not up yet) to apply a gradient to the background depending on what time of day it is. When the site is live I'll give an update.

From presto8 on 2011-03-17T04:41:15Z:

Thanks, Trev, for sharing your edits. Do you have a test case that was causing getDOY() to fail? It seems to be working ok for me.

From trevnorris on 2011-03-24T06:02:29Z:

Heh. I'm a dork. I changed your code to force getting the latest date, and didn't even bother to use three of the variables I'd set in SunriseSunset. When I tested your code I used getYear() and getMonth(). This was a mistake since I should have used getFullYear(), and getMonth() + 1.

You're calculations are correct. Guess that's what I get coding until 3 in the morning.

From presto8 on 2011-03-24T15:16:44Z:

We've all been there :-) Thanks for letting me know!