25

I like to keep track of sunrise and sunset times. For the past couple of years I've been doing this with a small program written with a popular library for my favorite programming language. The last two months I've been keeping track of these times more regularly than usual, and I happened to notice that on the day of the equinox the sunrise time jumped eight minutes as compared to the day before! I knew this was impossible and compared with NOAA, finding out that my rise and set times had been off for several days and in fact seemed to be off by about a minute for most of the year.

At this point, I'd like to just implement the calculations myself. What algorithms or formulas are available to do this computation?

skiphoppy
  • 97,646
  • 72
  • 174
  • 218
  • 8
    Frankly, Jason, I'm not sure if I belong here any more or not. I am so sick of finding that questions I asked a year ago are being hacked over and pulled onto other sites. It's a programming question, isn't it? – skiphoppy Jul 22 '11 at 19:35
  • 1
    if they are "hacked over" or pulled onto other sites, it's for a reason. would you go into a bank and ask the teller what gas prices are? i was just not convinced that this was a programming question, and i'm still not. there is no mention of anything to do with programming, just algorithms and computation. there's a [site for that](http://math.stackexchange.com/). You also have tagged your question as "astronomy". There's a [site for that](http://astronomy.stackexchange.com/) as well. It doesn't mean your question is bad or invalid, just that it's in the wrong venue. – Jason Jul 22 '11 at 20:28
  • 1
    To get NASA-level accuracy, use the CSPICE libraries: http://naif.jpl.nasa.gov/naif/tutorials.html If you re-ask this question on astronomy.stackexchange.com, I can give you a more complete answer (I don't want to answer a closed question). –  Jan 08 '16 at 17:57
  • Hey, I know I'm late, but I have written an MATLAB function to compute the sunrise and sunset times on the NOAA website. Follow [this link](http://stackoverflow.com/a/42938070/7649907) – Richard Mar 21 '17 at 21:07
  • You may want to consider the skyfield python library. Usage example: https://astronomy.stackexchange.com/a/30141 – Caesar Apr 24 '19 at 11:23

8 Answers8

11

You may consider reading Wikipedia's article on sunrise equations. The lead paragraph gives the equation:

cos(ωo) = -tan(φ) * tan(δ)

where:

  • ωo is the hour angle in degrees at either sunrise (when negative value is taken) or sunset (when positive value is taken) in degree (°)
  • φ is the latitude of the observer on the Earth in degrees
  • δ is the sun declination in degrees
Jonta
  • 393
  • 5
  • 25
8

If you want to match NOAA, you'll have to consult Jean Meeus' Astronomical Algorithms (mostly Chapter 15). And it's complicated! Martin Beckett is correct, you have to define the sunset. Typically this is the apparent rise or set of upper limb of the sun, which makes your "standard" altitide -5/6 degrees (not zero). And you can't calculate the sunrise or sunset directly with NOAA's accuracy. You'll have to create a governing set of equations for apparent right ascension and declination for the day in question and then interpolate the apparent right ascension and declination over time to find the exact rising and setting times at the standard altitude.

Hope this helps. I spent about a month digesting AA and re-writing all our solar code when I came across the same thing, and it still took over a year to sort out some of the corner cases where my code broke. So it will take some time to figure out. I'm not aware of any public code examples of this algorithm and don't have any to share at this moment, but I'm happy to help you through some headaches if I can.

mattexx
  • 6,456
  • 3
  • 36
  • 47
  • What about using NOAA's own algorithm (http://www.srrb.noaa.gov/highlights/sunrise/program.txt). Details described at http://www.srrb.noaa.gov/highlights/sunrise/calcdetails.html – Pat Mar 24 '11 at 16:31
  • @Pat NOAA's algorithms published here calculate solar position at a given time. This question is about calculating sunrise and sunset times, which is solving a time for a given position. The problems are related but not the same thing! – mattexx Mar 31 '11 at 06:06
  • @mattexx I am not sure what all is in the javascript, but I know that it powers their sunrise/set calculator (http://www.srrb.noaa.gov/highlights/sunrise/sunrise.html), which tells the time for sunrise/set based on location. As far as I understand, that's exactly what the OP wants to do. – Pat Mar 31 '11 at 16:54
  • @Pat Yes, their tool does calculate sunrise and sunset, but that part of the code is not made public by NOAA to my knowledge. I would love to see it if it is! BTW I have a local rubygem that calculates sunrise & sunset. I'm working on publishing it (trying to grok rubyforge release process). If you are really interested in seeing some code, I can send it over or point you to the published link once I get it up there. – mattexx Mar 31 '11 at 17:22
  • 5
    @matexx The code is there, on http://www.srrb.noaa.gov/highlights/sunrise/sunrise.html. It's just javascript, so `view source` will show you everything. – Pat Mar 31 '11 at 17:53
  • @Pat Thanks for that pointer! I've always been curious what they do differently. It looks like they do a two-step approximation, which I'm sure is fine and much faster than my interpolation. – mattexx Apr 01 '11 at 18:57
  • Just a side note. I went throught the whole javascript inside @Pat 's answer for a while, without noticing the updated version here: https://www.esrl.noaa.gov/gmd/grad/solcalc/ . Please, don't rush into the old calculator like I did. – Kar.ma Mar 27 '17 at 14:35
  • I have now realized the NOAA-algorithm (which is based on Meeus-AA) in Java, see the [API of my lib Time4J](http://time4j.net/javadoc-en/net/time4j/calendar/astro/SolarTime.html#sunrise--) – Meno Hochschild Sep 22 '17 at 10:38
4

Definitions of what constitutes sunrise/sunset can vary. For example, in ephem "rising and setting are defined as the moments when the upper limb of the body touches the horizon (that is, when the body’s alt plus radius equals zero)" [PyEphem Quick Reference].

#!/usr/bin/env python
import datetime
import ephem # to install, run `pip install pyephem`

o = ephem.Observer()
o.lat, o.long, o.date = '34:3', '-118:15', datetime.datetime.utcnow()
sun = ephem.Sun(o)
print "Los Angeles"
print "sunrise:", o.next_rising(sun), "UTC"
print "sunset:",o.next_setting(sun), "UTC"

Output

Los Angeles, CA
sunrise: 2010/3/30 13:42:43 UTC
sunset: 2010/3/30 02:11:50 UTC

If it is open-source library then you could fix it instead of creating a new one with new bugs.

jfs
  • 399,953
  • 195
  • 994
  • 1,670
4

For accuracy in the 5min range you have to consider 'which' sunset.
Do you want the time the bottom of the sun touches the horizon or the time the top of the sun passes below the horizon?

It takes 2mins for the sun to cross the horizon.
Below the 1min level you also need to take into account atmospheric refraction.

Martin Beckett
  • 94,801
  • 28
  • 188
  • 263
  • 1
    It doesn't take 2 minutes everywhere on earth for the sun to cross the horizon. –  Jan 14 '13 at 21:13
  • 1
    It can take the sun over 43 hours to rise or set: http://astronomy.stackexchange.com/questions/12824/how-long-does-a-sunrise-or-sunset-take –  Jan 08 '16 at 18:02
3

Have a look at this book:
"Practical Astronomy with your Calculator (Paperback)" by Peter Duffett-Smith.
It is quite old but still in print... link

Volker Voecking
  • 5,203
  • 2
  • 38
  • 35
2

In Ruby I wrote this for equation of time.

include Math

# degrees to radians = PI/180
to_r = PI/180.0

#radians to degrees = 180/PI
to_d = 180.0/PI

puts "Day, Declination, EofT"

# test a celestial year worth of values.
for jday in 1..366

  et = -7.633 * sin(jday * (2 * PI)/365.24) + 9.65 * sin((jday - 78) * 180/92 * to_r)
  a_sin = sin(23.433 * to_r) * sin((2 * PI/366) * (jday - 81))
  declination = asin(a_sin) * to_d
  puts "#{jday}, #{declination}, #{et}"

end

Then for the above equation:

# center disk and refraction factor have been considered.
cos_omega = sin(-0.83 * to_r) - tan(latitude * to_r) * tan(declination * to_r)
semi_diurnal_arc = acos(cos_omega)

There is a whole website devoted to this at http://www.analemma.com/

  • The key to these calculations are good libraries like the one for python above.
  • Also usage of Date and Time classes. I would look on rubyforge for something like ephem.
Dori
  • 915
  • 1
  • 12
  • 20
Douglas
  • 71
  • 4
0

I did see some interesting things on this NOAA page under the Technical Definitions and Computational Details heading, but I'm sure you've read that already.

The answer to the SO question "Position of the sun given time of day, and lat/long" and the above may actually be all you need.

As a side note (it doesn't answer your question directly), is there a reason you can't pull the NOAA data and use it as a lookup table instead of calculating it? Storage tends to be relatively cheap these days.

Community
  • 1
  • 1
lc.
  • 113,939
  • 20
  • 158
  • 187
  • I like the lookup table approach, but I want to know how to implement it in code, and at this point I want to know what algorithm is behind the data I'm using, since what I was using turned out to be so wonky. – skiphoppy Apr 01 '09 at 05:02
  • Besides, I'm also in the process of trying to replace a lookup table for equinoxes/solstices with an algorithm. :) – skiphoppy Apr 01 '09 at 05:02
  • I don't think a lookup table will work if the latitude and longitude are arbitrary. Re equinoxes, perhaps take a look at: http://astronomy.stackexchange.com/questions/13008/are-there-accurate-equinox-and-solstice-predictions-for-the-distant-past –  Jan 08 '16 at 17:59
0

You might want to look at an earlier entry on calculating the position of the sun. Specifically, the Solpos program that I pointed to has support for sunrise/sunset.

Community
  • 1
  • 1
Toybuilder
  • 11,153
  • 5
  • 28
  • 33