特定の日付の月相または年齢を計算するアルゴリズム、または特定の年の新月/満月の日付を見つけるアルゴリズムを知っている人はいますか?
グーグルは答えはいくつかの天文学の本にあると私に教えてくれますが、私は本当に私が単一のページだけを必要とするときに本全体を購入したくありません。
更新:
私はググリングについての私の声明をもう少し良くするべきでした。 (1900年代のように)一部の時間でしか機能しないソリューションを見つけました。そして、trigベースのソリューションは、私が望むよりも計算コストが高くなります。
彼のPython本のS Lottは、与えられた年のイースターを計算するためのいくつかのアルゴリズムを持っています、ほとんどは10行未満のコードであり、いくつかはグレゴリオ暦のすべての日に機能します。満月を見つける3月はイースターを見つけるための重要な部分なので、トリガーを必要とせず、グレゴリオ暦のすべての日付で機能するアルゴリズムがあるはずだと考えました。
私はいくつかのコードをPython=これまでしばらくの間移植しました。リンクするつもりでしたが、その間にウェブから落ちてしまったので、ほこりを払わなければなりませんでしたオフにして再度アップロードします John Walkerのmoontool から派生した moon.py を参照してください。
どちらの期間でも正確な期間については、これについての参照を見つけることはできませんが、著者はかなり厳密であるようです。つまり、はい、これはトリガーを使用しますが、これを何のために使用するのか、計算上非常に困難になります。 Python関数呼び出しのオーバーヘッドは、おそらくトリガー操作のコストよりも多くなります。コンピュータは、計算がかなり高速です。
コードで使用されるアルゴリズムは、次のソースから取得されます。
Meeus、Jean。天文アルゴリズム。リッチモンド:Willmann-Bell、1991。ISBN0-943396-35-2。
必須アイテム。 1冊しか購入しない場合は、この本かどうかを確認してください。アルゴリズムはコンピュータープログラムとしてではなく数学的に提示されますが、本のアルゴリズムの多くを実装するソースコードは、QuickBasic、Turbo Pascal、またはCのいずれかで出版社から個別に注文できます。Meeusは、デバッグに不可欠な多くの計算例を提供あなたのコード、そして頻繁に、正確さ、速度、複雑さ、そして長期的(数世紀から数千年)の妥当性の間で異なるトレードオフを持ついくつかのアルゴリズムを提示します。
ダフェット・スミス、ピーター。あなたの電卓で実用的な天文学。第三版ケンブリッジ:Cambridge University Press、1981。ISBN0-521-28411-2。
タイトルの単語電卓にもかかわらず;これは、惑星の位置、軌道、日食などを計算するソフトウェアの開発に興味がある場合に役立つリファレンスです。 Meeusよりも多くの背景情報が提供されます。これは、天文学にまだ精通していない人が、しばしば混乱する用語を学ぶのに役立ちます。与えられたアルゴリズムは、Meeusが提供するアルゴリズムよりも単純で正確ではありませんが、ほとんどの実際的な作業に適しています。
あなたが私のような人なら、慎重なプログラマーになろうとするでしょう。したがって、複雑な天文学の問題を解決しようとしているインターネット全体にランダムなコードが散在しているのを見ると緊張しますが、ソリューションが正しい理由を説明していません。
booksなどの慎重かつ完全なソリューションを含む信頼できるソースが必要であると考えています。例えば:
Meeus、Jean。天文アルゴリズム。リッチモンド:Willmann-Bell、1991。ISBN0-943396-35-2。
ダッフェ・スミス、ピーター。あなたの電卓で実用的な天文学。第三版ケンブリッジ:Cambridge University Press、1981。ISBN0-521-28411-2。
(静的なWebページとは異なり)エラーを修正できる、広く使用され、十分にテストされたオープンソースライブラリを信頼します。ここに、Python PyEphem ライブラリに基づいた質問への解決策があります 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)
これは戻ります
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')]
また、 pyephem —科学グレードの天文学ルーチン [ PyPI ]は、Pythonパッケージですが、 計算の根性があります) Cの場合 、そしてはと言います
-1369〜+2950の精度<0.05 "。
テーブルルックアップテクニックを使用して、三角関数の呼び出しを制限します。
ピエフェムはデフォルトで協定世界時(UTC)を使用します。太平洋のタイムゾーンで正確な満月のリストを生成するプログラムが必要でした。以下のコードは、指定された年の満月を計算してから、ephem.localtime()メソッドを使用してそれを調整し、目的のタイムゾーンに合わせて調整します。また、夏時間も適切に考慮されているようです。リチャードに感謝します。このコードは彼が書いたものに似ています。
#!/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)
上記のコードは次を返します:
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']
私はあなたがPythonを探していることを知っていますが、C#を理解できれば、そこに Chronos XP と呼ばれるオープンソースプロジェクトがあり、これは非常にうまく機能します。
高精度が必要ない場合は、いつでも(ab)月(またはlunisolar)カレンダークラス(Microsoft .NETのHijriCalendar
またはChineseLunisolarCalendar
など)を使用して(概算)を計算できます。 )任意の日付の月相。カレンダーの「日」プロパティとして、月(または月の太陽)のカレンダー日である常に月相に対応する(たとえば、1日目は新しい月、15日目は満月など)