To avoid the headaches associated with finding roughly two dozen similar solutions in the zig-zagging time zone boundaries , you might want to stick with UTC. If you want to deal with local time - it's going to get a little crazy if you also try to include daylight savings toggling on and off.
The points on the earth where the center of the sun coincides with the horizon (ignoring topography, oblateness, atmospheric refraction, the finite speed of light and other small effects) is just the circle on the earth where a cone drawn from the Sun intersects a spherical Earth.
above: A sphere inside a cone, from http://mathcentral.uregina.ca.
But the next step is hard - getting from that circle to the lat/lon coordinates on the surface, because the axis is tilted, and because the motion around the sun speeds up and slows down as the Earth revolves closer and farther from the Sun. These can be approximated by periodic functions with some coeficients, and that's what you will find in the math behind the first answer. For the second answer, I'll list two Python solutions - PyEphem and Skyfield. Both are easy to use, but you are separated from the actual math (in one case it's an ephemeris/table. The third answer is really a collection of NASA/JPL routines that are highly regarded but may involve more time for you to get up to speed compared to the Python packages.
Answer 1: Astronomical Algorithms
This is something you'll have to dig into a bit, but if you like to program, it may be exactly what you're looking for. The Gaisma website is one of my favorites on the internet - easy to use and presents a bunch of information in easy-to-understand graphics. Click around!
I believe that this site uses algorithms from the collection found at this NOAA site. Click around there as well. They provide Excel spreadsheets which contain the algorithms and other resources. The "main" resource is a collection of algorithms published in the book Astronomical Algorithms - Jean Meeus. From that Amazon page you can see that there are many similarly titled books. I'd recommend going to a library if possible, because it's (in my opinion) always good to go to libraries. However parts of these can be found on-line. For example, a few pages shown from the book Astronomical Formulae for Calculators (1988) include an interesting table of contents.
Answer 2: Python packages PyEphem and Skyfield
I'll copy a bit of the text from this answer:
The Python package PyEphem has been around and well supported, and is the pythonic reincarnation of XEphem. I haven't used it, but I believe it keeps enough information about orbital parameters at certain epochs to generate an ephemeris, including some gravitational perturbations. In other words, it's much more than planets moving on fixed elliptical orbits around a fixed sun. So I believe it runs without internet connection.
I never used it because I was recommended to look at Skyfield and it's exactly what I needed. It downloads a standard JPL ephemeris that you choose, and then just uses it from your hard drive after that. However, in order to deal with leap seconds and other time related effects, it occasionally needs to check the internet for leap second information updates, since these are arbitrary.
I don't know if Skyfield has a mode to avoid that. Actually that's a good question. If you work with a timescale that doesn't have leap seconds, I am not sure if it will run in its current version.
Both Skyfield and PyEphem Python packages have been written and are maintained by @BrandonRhodes.
I've included a simple Python script just to illustrate how Skyfield can be used. If you are comfortable with coding without curly braces, I would strongly recommend you give this a try. It's incredibly powerful and Pythonic.
This is just a starter - you need to add some better housekeeping to detect sunrises vs sunsets, and maybe a more global-type search in some cases. Actually there is some slightly tedious housekeeping necessary to make this work robustly.
note: you can turn on atmospheric refraction using the arguments in the
apparent() method. See the Skyfield API documentation for more info, and for a discussion about iterating using Skyfield methods - especially solving for times, see this helpful answer.
def alt_lonlat(lon, lat, t):
topo = earth.topos(lat, lon)
alt, az, dist = topo.at(trise).observe(sun).apparent().altaz() ## apparent() args for atmospheric refraction
from skyfield.api import load
import numpy as np
import matplotlib.pyplot as plt
import scipy.optimize as spo
data = load('de421.bsp')
ts = load.timescale()
# your example: '2014-08-27', sunset = '10:00 PM', sunrise = '7:30 AM'
trise = ts.utc(2014, 8, 27, 7, 30, 0)
tset = ts.utc(2014, 8, 27, 22, 0, 0)
earth = data['earth']
sun = data['sun']
zerozero = earth.topos(0.0, 0.0) # gotta start looking somewhere!
alt, az, dist = zerozero.at(trise).observe(sun).apparent().altaz() ## apparent() args for atmospheric refraction
print "at trise, JD = ", trise.tt
print "at (0N, 0E) Sun's altitude: ", alt.degrees, "azimuth: ", az.degrees
print "at (0N, 0E) Sun's distance (km): ", dist.km
# Find points on equator where sun is on horizon (rise or set) at t=trise
limits = ((0, 180.), (180, 360.))
lonzeros = 
for a, b in limits:
answer, info = spo.brentq(alt_lonlat, a, b,
full_output = True )
print "limits ", a, b, " converged! Found longitude (deg): ", answer
print "limits ", a, b, "whaaaa?"
# make some curves
lats = np.linspace(-60, 60, 13)
longis = 
for lon0 in lonzeros:
lons = 
for lat in lats:
answer, info = spo.brentq(alt_lonlat, lon0-90, lon0+90,
full_output = True )
lons = [(lon+180)%360.-180 for lon in lons] # wraparound at +/- 180
for lons in longis:
for lons in longis:
plt.plot(lons, lats, 'ok')
plt.title("at trise, JD = " + str(trise.tt))
Answer 3: SPICE Kernels
As pointed out by @barrycarter in this comment below this answer, the JPL SPICE Kernels are available. I'm not familliar with them but it's what NASA uses so it must be pretty good :)
Here are some screenshots for London, UK (Gaisma from here):