An interesting question that deserves a detailed answer.
The first problem. PyEphem takes its dates in the form of YYYY/mm/dd
, not YYYY-mm-dd
.
>>> from ephem import * >>> Date('2011-05-04') 2010/6/26 00:00:00 >>> Date('2011/05/04') 2011/5/4 00:00:00
(This behavior seems extremely unhelpful. I reported this to Brandon Craig Rhodes as a bug, and since PyEphem version 3.5.5.1 this behavior has been fixed.)
The second problem. In PyEphem, hlon
usually the heliocentric longitude of the body (longitude in the coordinate system oriented to the sun). It does not matter to the sun. So, as a special, undocumented exception, when you look at the hlon
and hlat
Sun, you get the heliocentric longitude and latitude of the Earth.
(It would be nice if this were documented. I reported this too , and PyEphem 3.7.5.1 now contains documentation that follows my recommendation.)
What you want, I suppose, is the longitude of the ecliptic in the sun. You can find the ecliptic coordinates of the body using the Pyephem Ecliptic
function:
>>> sun = Sun() >>> sun.compute('2011/05/04') >>> Ecliptic(sun).lon 43:02:58.9
However, findyourfate.com reports "13TA12" (i.e. 13 ° 12 'from Taurus, which corresponds to PyEphem 43:12:00). What happened to the missing 0:09? I think it comes down to choosing an era (that is, how much precession should be taken into account). By default, PyEphem uses the standard astronomical era J2000.0 . But findyourfate.com seems to be using the date era:
>>> sun.compute('2011/05/04', '2011/05/04') >>> Ecliptic(sun).lon 43:12:29.0
Hope this is all clear: ask if not.
If you want to generate the whole table in Python, you can do it like in the code below. I don't know an easy way to compute a lunar node using PyEphem, so I haven't implemented this bit. (I expect you can do this by iteratively searching, but I have not tried.)
from ephem import * import datetime import itertools import math zodiac = 'AR TA GE CN LE VI LI SC SG CP AQ PI'.split() def format_zodiacal_longitude(longitude): "Format longitude in zodiacal form (like '00AR00') and return as a string." l = math.degrees(longitude.norm) degrees = int(l % 30) sign = zodiac[int(l / 30)] minutes = int(round((l % 1) * 60)) return '{0:02}{1}{2:02}'.format(degrees, sign, minutes) def format_angle_as_time(a): """Format angle as hours:minutes:seconds and return it as a string.""" a = math.degrees(a) / 15.0 hours = int(a) minutes = int((a % 1) * 60) seconds = int(((a * 60) % 1) * 60) return '{0:02}:{1:02}:{2:02}'.format(hours, minutes, seconds) def print_ephemeris_for_date(date, bodies): date = Date(date) print datetime.datetime(*date.tuple()[:3]).strftime('%A')[:2], print '{0:02}'.format(date.tuple()[2]), greenwich = Observer() greenwich.date = date print format_angle_as_time(greenwich.sidereal_time()), for b in bodies: b.compute(date, date) print format_zodiacal_longitude(Ecliptic(b).long), print def print_ephemeris_for_month(year, month, bodies): print print (datetime.date(year, month, 1).strftime('%B %Y').upper() .center(14 + len(bodies) * 7)) print print 'DATE SID.TIME', for b in bodies: print '{0: <6}'.format(b.name[:6].upper()), print for day in itertools.count(1): try: datetuple = (year, month, day) datetime.date(*datetuple) print_ephemeris_for_date(datetuple, bodies) except ValueError: break def print_ephemeris_for_year(year): bodies = [Sun(), Moon(), Mercury(), Venus(), Mars(), Jupiter(), Saturn(), Uranus(), Neptune(), Pluto()] for month in xrange(1, 13): print_ephemeris_for_month(year, month, bodies) print