python c algorithm calendar astronomy

python - Algoritmo de la fase lunar/luna



c algorithm (8)

¿Alguien sabe un algoritmo para calcular la fase lunar o la edad en una fecha determinada o para encontrar las fechas de las lunas nuevas / completas en un año determinado?

Google me dice que la respuesta está en un libro de Astronomía, pero realmente no quiero comprar un libro completo cuando solo necesito una página.

Actualizar:

Debería haber calificado mi declaración acerca de googlear un poco mejor. Encontré soluciones que solo funcionaron en un subconjunto de tiempo (como el de 1900); y las soluciones basadas en trigonometría que serían más costosas computacionalmente de lo que me gustaría.

S Lott en su libro de Python tiene varios algoritmos para calcular la Pascua en un año determinado, la mayoría tiene menos de diez líneas de código y algunos trabajos para todos los días en el calendario gregoriano. Encontrar la luna llena en marzo es una pieza clave para encontrar la Pascua, así que pensé que debería haber un algoritmo que no requiera trigonometría y que funcione para todas las fechas en el calendario gregoriano.


Además, PyEphem [ PyPI ], que es un paquete de Python pero tiene las agallas computacionales en C , y eso dice

Precisión <0.05 "de -1369 a +2950.
Utiliza técnicas de búsqueda de tablas para limitar las llamadas a funciones trigonométricas.



Porté algo de código a Python para esto hace un tiempo. Iba a enlazar solo con él, pero resultó que, mientras tanto, se cayó de la web, así que tuve que desempolvarlo y cargarlo de nuevo. Ver moon.py que se deriva de la herramienta lunar de John Walker .

No puedo encontrar una referencia para esto por el tiempo que es preciso, pero parece que los autores fueron bastante rigurosos. Lo que significa que sí, usa trigonometría, pero no puedo imaginar qué diablos usarías para eso lo haría computacionalmente prohibitivo. La sobrecarga de llamadas a la función Python es probablemente más que el costo de las operaciones de activación. Las computadoras son bastante rápidas en la informática.

Los algoritmos utilizados en el código se extraen de las siguientes fuentes:

Meeus, Jean. Algoritmos astronómicos. Richmond: Willmann-Bell, 1991. ISBN 0-943396-35-2.

Una necesidad; Si solo compras un libro, asegúrate de que sea éste. Los algoritmos se presentan matemáticamente, no como programas informáticos, pero el código fuente que implementa muchos de los algoritmos del libro se puede solicitar por separado al editor, ya sea en QuickBasic, Turbo Pascal o C. Meeus proporciona muchos ejemplos de cálculos que son esenciales para la depuración. su código, y con frecuencia presenta varios algoritmos con diferentes compromisos entre precisión, velocidad, complejidad y validez a largo plazo (siglo y milenios).

Duffett-Smith, Peter. Astronomía práctica con tu calculadora. 3ª ed. Cambridge: Cambridge University Press, 1981. ISBN 0-521-28411-2.

A pesar de la palabra calculadora en el título; Esta es una referencia valiosa si está interesado en desarrollar software que calcule posiciones planetarias, órbitas, eclipses y similares. Se proporciona más información de fondo que en Meeus, que ayuda a aquellos que no están versados ​​en astronomía a aprender la terminología que a menudo es confusa. Los algoritmos proporcionados son más simples y menos precisos que los proporcionados por Meeus, pero son adecuados para el trabajo más práctico.


Pyephem utiliza por defecto el tiempo universal coordinado (UTC). Quería un programa que generara una lista de lunas completas que fuera precisa en la zona horaria del Pacífico. El código a continuación calculará las lunas completas para un año determinado y luego lo ajustará utilizando el método ephem.localtime () para calibrar la zona horaria deseada. También parece tener en cuenta adecuadamente el horario de verano. Gracias a Richard, este código es similar a lo que había escrito.

#!/usr/bin/python import datetime import ephem import os import time # Set time zone to pacific os.environ[''TZ''] = ''US/Pacific'' time.tzset() print("Time zone calibrated to", os.environ[''TZ'']) def get_full_moons_in_year(year): """ Generate a list of full moons for a given year calibrated to the local time zone :param year: year to determine the list of full moons :return: list of dates as strings in the format YYYY-mm-dd """ moons = [] date = ephem.Date(datetime.date(year - 1, 12, 31)) end_date = ephem.Date(datetime.date(year + 1, 1, 1)) while date <= end_date: date = ephem.next_full_moon(date) # Convert the moon dates to the local time zone, add to list if moon date still falls in desired year local_date = ephem.localtime(date) if local_date.year == year: # Append the date as a string to the list for easier comparison later moons.append(local_date.strftime("%Y-%m-%d")) return moons moons = get_full_moons_in_year(2015) print(moons)

El código de arriba devolverá:

Time zone calibrated to US/Pacific [''2015-01-04'', ''2015-02-03'', ''2015-03-05'', ''2015-04-04'', ''2015-05-03'', ''2015-06-02'', ''2015-07-01'', ''2015-07-31'', ''2015-08-29'', ''2015-09-27'', ''2015-10-27'', ''2015-11-25'', ''2015-12-25'']


Sé que estás buscando Python, pero si puedes entender C # hay un proyecto de código abierto llamado Chronos XP que lo hace muy bien.


Si eres como yo, tratas de ser un programador cuidadoso. Así que te pone nervioso cuando ves un código aleatorio esparcido por Internet que pretende resolver un problema astronómico complejo, pero no explica por qué la solución es correcta.

Usted cree que debe haber fuentes autorizadas, como libros que contengan 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 tu calculadora. 3ª ed. Cambridge: Cambridge University Press, 1981. ISBN 0-521-28411-2.

Usted deposita su confianza en 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 a su pregunta basada en la biblioteca PyEphem , utilizando la interfaz de Fases de la Luna .

#!/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'')]


Si no necesita alta precisión, siempre puede (ab) usar una clase de calendario lunar (o lunisolar) (por ejemplo, HijriCalendar o ChineseLunisolarCalendar en Microsoft .NET) para calcular la fase lunar (aproximada) de cualquier fecha, como el calendario La propiedad "día del mes", al ser un día calendario lunar (o lunisolar), siempre corresponde a la fase lunar (por ejemplo, el día 1 es la luna nueva, el día 15 es la luna llena, etc.)


Un rápido google reveló this .