Retrieve Sunrise, Sunset & Twilight Info in Ruby

Sunrise, Sunset & Twilight

TwilightI was curious about the exact time of sunrise & sunset at my location, so I found this US Naval Observatory site. In the process, I learned a more precise definition of twilight. I wanted to be able to automate the process of retrieving the information, so my first attempt was to simply put the query parameters used in the form in the URL as an HTTP GET request, but the server wouldn’t accept that, so I needed to issue an HTTP POST request.

Ruby Code

Ruby is a great language for this sort of task, so I put together the following simple program:

require 'net/http'

YOUR_ID    = ''    # A unique ID per comment above
YOUR_CITY  = ''    # The name of your city
YOUR_STATE = ''    # Two letter state abbreviation

now   = Time.now
month = now.month
day   = now.day + 1 # Tomorrow
year  = now.year

Net::HTTP.start('aa.usno.navy.mil') do |query|
  response = query.post('/cgi-bin/aa_pap.pl',
    "FFX=1&ID=#{YOUR_ID}&xxy=#{year}&xxm=#{month}&xxd=#{day}&st=#{YOUR_STATE}&place=#{YOUR_CITY}&ZZZ=END")
  if response.body =~ /Begin civil twilight[^0-9]*(\d+:\d{2} [ap].m.).*Sunrise[^0-9]*(\d+:\d{2} [ap].m.).*Sunset[^0-9]*(\d+:\d{2} [ap].m.).*End civil twilight[^0-9]*(\d+:\d{2} [ap].m.)/m
    puts "#{month}/#{day}/#{year}"
    puts "Begin Twilight: #{$1}"
    puts "Sunrise       : #{$2}"
    puts "Sunset        : #{$3}"
    puts "End Twilight  : #{$4}"
  end
end

You just need to edit the three constants that begin with YOUR_. The id used on the Navy web form is ‘AA’, but they have a comment in the HTML that requests you use a unique id of your own up to 8 characters to help them with tracking. You can find a more complete version of the code in my github profile.

Emacs Goodness

After writing the above Ruby script, I made it executable, ‘chmod +x sunrise.rb’, and placed it in my path so I could write a simple Emacs function to invoke it.

(defun bja-sunrise ()
  "Display sunrise, sunset & twilight information."
  (interactive)
  (shell-command "sunrise.rb"))

Imagine my surprise when I invoked the Emacs apropos help ‘C-h a’ to see my newly defined function and discovered that Emacs, naturally, already has several commands to display sunrise/sunset information!

calendar-mouse-sunrise/sunset
Show sunrise/sunset times for mouse-selected date.
calendar-sunrise-sunset
Local time of sunrise and sunset for date under cursor.
sunrise-sunset
Local time of sunrise and sunset for today. Accurate to a few seconds.

It doesn’t, however, display twilight information, so my simple function still has a purpose in life. Emacs is awesome :)

Tags: , , , , , ,

  1. Justin’s avatar

    Thanks for this code, I was trying to do this very thing for a rails project I am working on. Keep up the good work!

  2. Fredrik’s avatar

    Nice, however this information can also be calculated by using a Public Domain C-library. Check out the links in my Acknowledgements. Thanks!

  3. Brian Adkins’s avatar

    @Fredrik – thanks for the link. I entered a city and a latitude/longitude into the web site for which you provided a link. I got an error both times. The web site that I interface with allows using a lat/lon which is nice if you want the info for your particular area.

    When I click on one of the cities provided on your web site though, the graphics are very nice. You might consider adding the total daylight to the slider – maybe in the date rectangle.

  4. Fredrik’s avatar

    @Brian, I’ll add both things to my todo, thanks for the tips!