Si eres como yo, intenta ser un programador cuidadoso. Por lo tanto, te pone nervioso cuando ves código aleatorio disperso por Internet que pretende resolver un problema astronómico complejo, pero no explica por qué la solución es correcta.
Cree que debe haber fuentes autorizadas como libros que contienen soluciones cuidadosas y completas. Por ejemplo:
Meeus, Jean. Algoritmos Astronómicos. Richmond: Willmann-Bell, 1991. ISBN 0-943396-35-2.
Duffett-Smith, Peter. Astronomía práctica con su calculadora. 3ª ed. Cambridge: Cambridge University Press, 1981. ISBN 0-521-28411-2.
Confíe en las bibliotecas de código abierto ampliamente utilizadas y probadas que pueden corregir sus errores (a diferencia de las páginas web estáticas). Aquí, entonces, hay una solución de Python para su pregunta basada en la biblioteca PyEphem, usando la interfaz Phases of the Moon.
#!/usr/bin/python
import datetime
import ephem
def get_phase_on_day(year,month,day):
"""Returns a floating-point number from 0-1. where 0=new, 0.5=full, 1=new"""
#Ephem stores its date numbers as floating points, which the following uses
#to conveniently extract the percent time between one new moon and the next
#This corresponds (somewhat roughly) to the phase of the moon.
#Use Year, Month, Day as arguments
date=ephem.Date(datetime.date(year,month,day))
nnm = ephem.next_new_moon (date)
pnm = ephem.previous_new_moon(date)
lunation=(date-pnm)/(nnm-pnm)
#Note that there is a ephem.Moon().phase() command, but this returns the
#percentage of the moon which is illuminated. This is not really what we want.
return lunation
def get_moons_in_year(year):
"""Returns a list of the full and new moons in a year. The list contains tuples
of either the form (DATE,'full') or the form (DATE,'new')"""
moons=[]
date=ephem.Date(datetime.date(year,01,01))
while date.datetime().year==year:
date=ephem.next_full_moon(date)
moons.append((date,'full'))
date=ephem.Date(datetime.date(year,01,01))
while date.datetime().year==year:
date=ephem.next_new_moon(date)
moons.append((date,'new'))
#Note that previous_first_quarter_moon() and previous_last_quarter_moon()
#are also methods
moons.sort(key=lambda x: x[0])
return moons
print get_phase_on_day(2013,1,1)
print get_moons_in_year(2013)
Esto devuelve
0.632652265318
[(2013/1/11 19:43:37, 'new'), (2013/1/27 04:38:22, 'full'), (2013/2/10 07:20:06, 'new'), (2013/2/25 20:26:03, 'full'), (2013/3/11 19:51:00, 'new'), (2013/3/27 09:27:18, 'full'), (2013/4/10 09:35:17, 'new'), (2013/4/25 19:57:06, 'full'), (2013/5/10 00:28:22, 'new'), (2013/5/25 04:24:55, 'full'), (2013/6/8 15:56:19, 'new'), (2013/6/23 11:32:15, 'full'), (2013/7/8 07:14:16, 'new'), (2013/7/22 18:15:31, 'full'), (2013/8/6 21:50:40, 'new'), (2013/8/21 01:44:35, 'full'), (2013/9/5 11:36:07, 'new'), (2013/9/19 11:12:49, 'full'), (2013/10/5 00:34:31, 'new'), (2013/10/18 23:37:39, 'full'), (2013/11/3 12:49:57, 'new'), (2013/11/17 15:15:44, 'full'), (2013/12/3 00:22:22, 'new'), (2013/12/17 09:28:05, 'full'), (2014/1/1 11:14:10, 'new'), (2014/1/16 04:52:10, 'full')]
El mismo problema estaba en que aquí manojos de veces ocultos en el problema de determinar la fecha de Pascua, pelusa, el Viernes Santo, y/o Pascua. – nategoose
Un modelo astronómico preciso es inevitablemente complicado; el cálculo para la luna llena de la que deriva la fecha de Pascua (ver http://en.wikipedia.org/wiki/Paschal_full_moon) usa un modelo simplificado. –
Un gran uso para el moon.py citado en la respuesta elegida es escribir una aplicación GUI (yo iría con GTK) para mostrar realmente la fase lunar con una imagen de la luna (en realidad estoy tratando de hacer esto, que se volvió considerablemente más fácil con esta pregunta y sus respuestas ...) – heltonbiker